Icons in the Thinkwise Software Factory
Every entity, field, and bound task below was confirmed live against a real connected model (domain
sf/software_development) — not guessed from documentation. The semantic guidance (which concept fits
which object/action/state) is design guidance, not a database rule; it lives in
references/icon_selection_guide.md to keep this file focused on mechanics. Follow
thinkwise_software_factory_mcp_base for connector/model/branch resolution and the shared
confirm-before-mutate / ask-don't-default rules before making any of the writes described here.
The repository: icon / icon_grp / icon_tag
| Entity |
Key |
Purpose |
icon |
(model_id, branch_id, icon_id) |
One uploaded image. icon (SQLSERVER_SF.FileContract) and icon_data (Edm.Binary) carry the file; icon_title and icon_extension are separate scalar fields; icon_display is a read-only computed "{icon_title}.{icon_extension}" (verified live, e.g. icon_title="snacks-icon", icon_extension="svg" → icon_display="snacks-icon.svg"). icon_grp_id is optional — a live sample across several real models showed most icons left it blank; grouping is opt-in, not enforced. order_no_grp_or_item sorts within a group. |
icon_grp |
(model_id, branch_id, icon_grp_id) |
A flat label for organizing the repository (icon_grp_description, order_no). No nesting — same flat shape as list_bar_grp/tile_grp. |
icon_tag |
(model_id, branch_id, icon_id, tag_id) |
The platform's generic tagging mechanism (tag entity) applied to an icon, plus a free value. A second, orthogonal way to classify an icon beyond icon_grp_id — e.g. tag by visual family/source without forcing every icon into one group. |
Both icon and icon_grp are branch-scoped like every other design-time object (model_id/branch_id
in the key) — see thinkwise_software_factory_mcp_base on why an unfiltered query can silently mix rows
from an unrelated model/branch.
Bound tasks on icon (verified)
| Task |
Parameters |
Effect |
task_rename_icon_name |
icon_id, and all of from_icon_name, from_icon_name_no_extension, from_icon_name_extension, to_icon_name, to_icon_name_extension (every one mandatory) |
Renames the icon's filename. Supply the icon's current title/extension exactly, not just the target — this isn't a simple "new name" call. |
task_enrichment_decolorize_svg |
bound by icon_id, but its one real parameter is icon_title (mandatory) — re-supply the icon's current title |
Strips embedded fill color from an SVG so Universal UI's theme-based recoloring can work (light/dark). Only meaningful for monochrome SVG concepts, not photographic/multicolor assets. |
task_update_icon_usage |
from_icon_id (bound) + upload_new_icon (bool) + either to_existing_icon_id or to_new_icon/to_new_icon_data |
The consolidation tool: redirects every existing assignment of from_icon_id across the whole model to a different existing icon (dedup a duplicate) or to a freshly uploaded replacement — in one step, instead of hand-editing every *_icon_id field that pointed at it. |
task_download_selected_icon |
icon, icon_data |
Downloads a copy of the icon. |
task_get_icon_as_varbinary_literal |
icon_id → varbinary_literal |
Produces a SQL varbinary literal for the icon's bytes — useful for seeding icons via a control procedure/script rather than the API's own upload path (see below). |
task_delete_icon |
icon_id |
Deletes the icon record. Check the assignment points below first — nothing here blocks the delete just because the icon is still referenced. |
Bound tasks on icon_grp
task_rename_icon_grp (from_icon_grp_id/to_icon_grp_id) and task_delete_icon_grp — no create
task exists; add a new icon_grp as a plain record (icon_grp_id, icon_grp_description, order_no),
the same pattern used for module_grp elsewhere in the platform.
Uploading a brand-new icon — unverified through this API
icon.icon is typed SQLSERVER_SF.FileContract, a file-upload field distinct from the plain
icon_data binary column, and there is no bound "upload" task — a new icon looks like a plain add
setting icon/icon_data/icon_title/icon_extension together. This mechanic has not been
exercised live in this session — whether an MCP connector's staging flow can actually carry a
FileContract payload (vs. only reading/renaming/reassigning existing icons) is unconfirmed. Until
verified, treat uploading a new file as something to do in the Software Factory's own Icons
repository UI, and use the API confidently for everything else here: reading, grouping, tagging,
renaming, decolorizing, consolidating (task_update_icon_usage), and assigning an existing icon_id
to any of the fields below.
Every verified assignment point
Confirmed by pulling the full property list of every candidate entity against the live domain (not just
icon's own reverse navigation, which misses one real case below) — this is the complete set of
entities that carry an icon-referencing field, not a curated subset.
Almost every one of them carries a pair, not a single field: an <x>icon_id (or image_id on
cube_view_field_conditional_layout) that's a foreign key into the shared icon repository, and its
own local <x>icon/<x>icon_data (SQLSERVER_SF.FileContract + Edm.Binary) that uploads a file
straight onto that row, bypassing the repository entirely. Both are always present or absent together,
with one verified exception: tab_task has only the local icon/icon_data pair — a
table-specific task icon override can never be picked from the shared repository, only uploaded fresh
onto that one tab_task row.
Prefer the _id repository field whenever both exist. The local icon/icon_data pair is a
parallel, older upload mechanism — it works, but an icon set that way doesn't show up in the shared
repository for reuse, can't be redirected via task_update_icon_usage, and won't benefit from
task_enrichment_decolorize_svg being run once and shared everywhere. Reach for it only where there is
no _id alternative (tab_task) or the user explicitly wants a one-off asset kept out of the shared
repository.
| Object |
Repository field |
Local-upload field(s) |
What it controls |
branch |
icon_id |
icon/icon_data |
The branch's own icon (design-time — shown wherever a branch is picked/listed, not necessarily an end-user surface). |
tab |
icon_id |
icon/icon_data |
A table/view's icon — its document, menu item, and detail navigation. |
tab_variant_overview |
icon_id |
icon/icon_data |
Per-variant override of a table's icon. |
task |
icon_id |
icon/icon_data |
A task's icon — action bars, menus, wherever the task appears. |
task_variant_overview |
icon_id |
icon/icon_data |
Per-variant override of a task's icon. |
tab_task |
(none) |
icon/icon_data only |
A table-specific override of a task's icon for one table's action bar — upload-only, no repository option, verified live. |
report |
icon_id |
icon/icon_data |
A report's icon. |
report_variant_overview |
icon_id |
icon/icon_data |
Per-variant override of a report's icon. |
tab_prefilter |
icon_id |
icon/icon_data |
A single prefilter's icon. |
tab_prefilter_grp |
icon_id |
icon/icon_data |
A prefilter group's icon. |
menu |
icon_id |
icon/icon_data |
The whole menu's icon (shown when switching between menus). |
list_bar_grp |
icon_id |
icon/icon_data |
A list-bar menu group's icon. Weak entity — its edit key is (model_id, branch_id, menu_id, list_bar_grp_id), not list_bar_grp_id alone; see thinkwise_software_factory_mcp_base on weak-entity edit keys. |
tile_grp |
icon_id |
icon/icon_data |
A tile group's icon. |
module_grp |
icon_id |
icon/icon_data |
A legacy tree menu's module-group icon. |
tab_task_grp |
icon_id |
icon/icon_data |
A table action-bar task-group icon. |
tab_report_grp |
icon_id |
icon/icon_data |
A table action-bar report-group icon. |
cube_view |
cube_view_icon_id |
cube_view_icon/cube_view_icon_data |
A cube view's icon (e.g. on a BI menu/tile). |
msg_option |
icon_id |
icon/icon_data |
A modeled message's option button (confirm/retry/cancel-style choices) — see thinkwise_software_factory_messages. |
elemnt |
icon_id |
icon/icon_data |
A single domain element's (enum value's) icon — renders when the owning dom.control_id is set to an icon-based control (an image/icon combo or radio-style presentation), not for a plain text/combo domain. |
cube_view_field_conditional_layout |
image_id (confirmed FK into icon.icon_look_up, same repository, just named "image") |
image/image_data |
An icon-based conditional layout — showing an icon instead of/alongside color for a computed condition. See thinkwise_software_factory_conditional_layouts and thinkwise_software_factory_cubes. |
screen_component |
tab_page_icon_id |
tab_page_icon/tab_page_icon_data |
A custom screen component's tab-page icon (multi-page custom components). screen_component_type_icon/_data also exists but is the component type's own icon, not settable per instance. |
col |
form_next_grp_icon_id, next_tab_icon_id |
matching form_next_grp_icon/_data, next_tab_icon/_data |
A column's "jump to related form group" / "jump to related tab" navigation icons. |
report_parmtr |
same two _id fields |
same local pairs |
Same navigation-icon pattern, on a report parameter. |
task_parmtr |
same two _id fields |
same local pairs |
Same navigation-icon pattern, on a task parameter. |
tab_variant_form_overview |
same two _id fields |
same local pairs |
Per-variant override of a table column's navigation icons. |
report_variant_form_overview |
same two _id fields |
same local pairs |
Per-variant override of a report parameter's navigation icons. |
task_variant_form_overview |
same two _id fields |
same local pairs |
Per-variant override of a task parameter's navigation icons. |
Notably absent: tile and list_bar_item carry no icon field of their own at all — a menu item
always shows the icon of whatever it points to (tab/report/task, or that object's variant
override), confirming the platform's own "menu item icon = referenced object's icon" convention rather
than a separate menu-only vocabulary. action_bar likewise carries no icon field — per-action display
(icon-only vs. icon+text vs. overflow) is controlled by action_bar's own default_display_type enum
(icon_text_*/text_only_*/icon_only_*/overflow/hidden values, verified live), not by a separate
icon field. task_button/report_button were checked directly and don't exist as entity sets in this
domain at all.
Assigning or changing an icon
Whenever a skill or task involves creating or configuring any object in the table above (a table, a
task, a report, a prefilter, a menu/group, a cube view, a domain element on an icon-capable domain, a
message option, a form/report navigation group, an icon-based conditional layout), assigning it a
suitable icon is part of finishing that object, not an optional extra — don't leave the field unset
by default just because the field itself isn't mandatory — unless the model's existing convention for
that exact object type says otherwise (step 0 below).
- Follow the model's existing convention for this object type — don't impose one. Before assigning
an icon to a newly created object, check how existing rows of that same entity (e.g. other
list_bar_grp rows on the same or other menus, other menu rows, other tab_prefilter_grp rows)
actually use the field: count how many have the _id/local-upload field set vs. null.
- If existing rows overwhelmingly do use icons, assign one to the new object too (proceed with
steps 1+ below).
- If existing rows overwhelmingly don't use icons (e.g. a model has several
list_bar_grp rows
and none of them carry an icon), don't add one to the new object either — match the model's
established look rather than making one object inconsistent with its peers. Say so explicitly
("this model's existing menu groups don't use icons, so I'm leaving this one unset to match") rather
than silently skipping it.
- If usage is mixed with no clear majority, or there are no existing rows of that type to compare
against (this is the first one), fall back to the default in the paragraph above: assign an icon.
- Judge this per object type, not globally — a model can consistently iconify
tab rows while
never iconifying list_bar_grp rows; don't let one type's convention decide another's.
- Reuse before uploading. Query
icon (optionally filtered by icon_grp_id/icon_tag) for an
existing icon matching the concept before creating a new one — see
references/icon_selection_guide.md for how to judge "matching."
- If nothing in the repository fits, don't upload or pick unilaterally — ask the user. Present
what you searched for and why nothing matched, then ask (via
AskUserQuestion or a plain question)
whether they want to (a) upload a specific icon file themselves for you to add to the repository, or
(b) name a specific existing icon (even an imperfect fit) to use instead. This mirrors
thinkwise_software_factory_maps_component's existing rule for elemnt.icon — don't silently pick a
"close enough" icon or leave the field blank when no confident match exists.
- Set the target field to the chosen
icon_id (repository) via patch_resource/stage_resource —
prefer the _id field over the entity's own local icon/icon_data upload pair wherever both exist
(see "Prefer the _id repository field" above); use the local pair only on tab_task, where it's the
only option, or when the user explicitly wants a one-off file kept out of the shared repository.
- Before changing an icon that's already assigned elsewhere, check whether other objects share it —
an unrelated screen can shift visually if you edit or replace a widely-reused icon. Prefer
task_update_icon_usage (redirect this object's assignment to a different, more specific icon by
changing the field directly; use the task only when you actually want to repoint every usage of one
icon at once, e.g. consolidating duplicates).
- Per
thinkwise_software_factory_mcp_base's confirm-before-mutate rule: state which icon (existing or
new) you're assigning and why before the first mutating call, especially for a menu/table/task icon
that's user-visible across the whole application, not just a low-stakes internal object.
- After setting
dom.control_id to an icon-capable control (e.g. IMAGE_COMBO) so elemnt.icon_id
will actually render: if the domain's underlying data type is numeric (SMALLINT/tinyint/etc.), the
Software Factory silently resets dom.alignment to right (1) as a side effect of the control_id
change — even though a left-aligned icon/enum-style presentation is what you actually want. Confirmed
live: setting control_id=IMAGE_COMBO on 4 numeric domains flipped all 4 to alignment=1, while
sibling element-bearing domains in the same model that hadn't had their control_id touched stayed at
alignment=0 (left). Re-read dom.alignment right after any control_id write on a numeric domain
and patch it back to left (numeric value 0 — the string key "left" is rejected with
invalid_input) unless the model's own convention for that domain type is actually right-aligned.
Auditing a model for missing icons
When asked to find every icon field that's currently unset — rather than assigning icons for objects
already being built — don't treat every null *icon_id/image_id as a gap to fill. Several of the
fields in the table above are optional per-row overrides for a feature that many models never turn on,
so they're null by design, not by omission:
- Navigation icons (
col/report_parmtr/task_parmtr/*_variant_form_overview's
form_next_grp_icon_id/next_tab_icon_id) only render when that column/parameter actually has the
matching jump-to-group/jump-to-tab navigation configured. If no row in the model uses that
navigation feature at all, leave these alone.
elemnt.icon_id only renders when the owning dom.control_id is an icon-capable control (see
the pre-flight checklist below) — a domain element on a plain COMBO/text control never displays it.
screen_component.tab_page_icon_id only matters for a multi-page custom screen component — a
single-page component (or a model with no multi-page custom components at all) leaves it null
meaningfully.
tab_task's local icon/icon_data override only matters where a table actually overrides one
of its tasks' icons for its own action bar — most tables never do, so an empty value there isn't a
gap.
Before flagging any of these as "missing," check whether the underlying feature is used anywhere in
the model at all (e.g. count rows where the relevant field is set, not just where it's null) — a
feature sitting at zero usage means there's nothing to iconify, not several fields to fill in.
Pre-flight checklist
- Confirmed connector/model/branch per
thinkwise_software_factory_mcp_base.
- For a newly created object, checked whether existing rows of that same entity commonly use icons
before assigning (or skipping) one — matched the model's existing convention per object type rather
than defaulting to always-on; only defaulted to assigning when usage was mixed or there was no
existing row to compare against. See "Follow the model's existing convention" (step 0) above.
- Searched the existing
icon/icon_grp/icon_tag repository for a matching concept before proposing
a new upload.
- Picked the specific field for the object at hand from the table above — note several entities have
two variant-scoped fields (base
*_overview vs. the plain entity), the two navigation-icon fields
(form_next_grp_icon_id vs. next_tab_icon_id) are visibly different UI hooks, and most objects have
both a repository _id field and a local icon/icon_data upload pair — used the _id field
unless the object is tab_task (upload-only) or the user wants a one-off asset.
- If no existing icon in the repository fit, asked the user to upload one or name a specific icon,
rather than picking the closest match unilaterally or leaving the field unset.
- For a status/enum-driven icon, checked that the owning
dom.control_id is actually an icon-capable
control before setting elemnt.icon_id — on a plain text/dropdown domain the field would go unused.
- After setting
dom.control_id on a numeric-typed domain, re-checked dom.alignment and reset it to
left if the Software Factory silently flipped it to right (see step 6 above) — don't assume
alignment is untouched by a control_id change.
- Read
references/icon_selection_guide.md's relevant section (action/object/status/menu/prefilter/
report/form-group) before picking the concept, not just the mechanical field.
- Before replacing or heavily editing a shared icon, checked its other assignments; used
task_update_icon_usage for a genuine one-to-many consolidation rather than hand-editing every field.
- New-file upload not yet verified via this API — routed actual file uploads through the Software
Factory's own Icons repository UI unless/until confirmed otherwise.
- If auditing an existing model for missing icons (not authoring new objects), confirmed the
underlying optional feature (nav icons, multi-page screen components, per-table task icon
overrides) is actually used before treating a null field as a gap — see "Auditing a model for
missing icons" above.
1---2name: thinkwise-software-factory-icons3description: Reference guide for the icon repository (icon/icon_grp/icon_tag) and every verified place an icon can be assigned in a Thinkwise Software Factory model — tables, tasks, reports, prefilters, menus, cube views, domain elements, message options, form/report navigation, conditional layouts — plus the semantic vocabulary for choosing the right icon per object/action/state. Use whenever an MCP connector with Software Factory access creates, inspects, reuses, replaces, or assigns an icon, or before calling get_entity_definition/execute_odata_query/stage_resource/stage_task against icon, icon_grp, icon_tag, or any `*icon_id`/`image_id` field.4---56# Icons in the Thinkwise Software Factory78Every entity, field, and bound task below was confirmed live against a real connected model (domain9`sf/software_development`) — not guessed from documentation. The semantic guidance (which concept fits10which object/action/state) is design guidance, not a database rule; it lives in11`references/icon_selection_guide.md` to keep this file focused on mechanics. Follow12`thinkwise_software_factory_mcp_base` for connector/model/branch resolution and the shared13confirm-before-mutate / ask-don't-default rules before making any of the writes described here.1415## The repository: `icon` / `icon_grp` / `icon_tag`1617| Entity | Key | Purpose |18|---|---|---|19| `icon` | `(model_id, branch_id, icon_id)` | One uploaded image. `icon` (`SQLSERVER_SF.FileContract`) and `icon_data` (`Edm.Binary`) carry the file; `icon_title` and `icon_extension` are separate scalar fields; `icon_display` is a read-only computed `"{icon_title}.{icon_extension}"` (verified live, e.g. `icon_title="snacks-icon"`, `icon_extension="svg"` → `icon_display="snacks-icon.svg"`). `icon_grp_id` is optional — a live sample across several real models showed most icons left it blank; grouping is opt-in, not enforced. `order_no_grp_or_item` sorts within a group. |20| `icon_grp` | `(model_id, branch_id, icon_grp_id)` | A flat label for organizing the repository (`icon_grp_description`, `order_no`). No nesting — same flat shape as `list_bar_grp`/`tile_grp`. |21| `icon_tag` | `(model_id, branch_id, icon_id, tag_id)` | The platform's generic tagging mechanism (`tag` entity) applied to an icon, plus a free `value`. A second, orthogonal way to classify an icon beyond `icon_grp_id` — e.g. tag by visual family/source without forcing every icon into one group. |2223Both `icon` and `icon_grp` are branch-scoped like every other design-time object (`model_id`/`branch_id`24in the key) — see `thinkwise_software_factory_mcp_base` on why an unfiltered query can silently mix rows25from an unrelated model/branch.2627### Bound tasks on `icon` (verified)2829| Task | Parameters | Effect |30|---|---|---|31| `task_rename_icon_name` | `icon_id`, **and all of** `from_icon_name`, `from_icon_name_no_extension`, `from_icon_name_extension`, `to_icon_name`, `to_icon_name_extension` (every one mandatory) | Renames the icon's filename. Supply the icon's *current* title/extension exactly, not just the target — this isn't a simple "new name" call. |32| `task_enrichment_decolorize_svg` | bound by `icon_id`, but its one real parameter is `icon_title` (mandatory) — re-supply the icon's current title | Strips embedded fill color from an SVG so Universal UI's theme-based recoloring can work (light/dark). Only meaningful for monochrome SVG concepts, not photographic/multicolor assets. |33| `task_update_icon_usage` | `from_icon_id` (bound) + `upload_new_icon` (bool) + either `to_existing_icon_id` **or** `to_new_icon`/`to_new_icon_data` | The consolidation tool: redirects **every** existing assignment of `from_icon_id` across the whole model to a different existing icon (dedup a duplicate) or to a freshly uploaded replacement — in one step, instead of hand-editing every `*_icon_id` field that pointed at it. |34| `task_download_selected_icon` | `icon`, `icon_data` | Downloads a copy of the icon. |35| `task_get_icon_as_varbinary_literal` | `icon_id` → `varbinary_literal` | Produces a SQL varbinary literal for the icon's bytes — useful for seeding icons via a control procedure/script rather than the API's own upload path (see below). |36| `task_delete_icon` | `icon_id` | Deletes the icon record. Check the assignment points below first — nothing here blocks the delete just because the icon is still referenced. |3738### Bound tasks on `icon_grp`3940`task_rename_icon_grp` (`from_icon_grp_id`/`to_icon_grp_id`) and `task_delete_icon_grp` — **no create41task exists**; add a new `icon_grp` as a plain record (`icon_grp_id`, `icon_grp_description`, `order_no`),42the same pattern used for `module_grp` elsewhere in the platform.4344### Uploading a brand-new icon — unverified through this API4546`icon.icon` is typed `SQLSERVER_SF.FileContract`, a file-upload field distinct from the plain47`icon_data` binary column, and there is no bound "upload" task — a new icon looks like a plain add48setting `icon`/`icon_data`/`icon_title`/`icon_extension` together. **This mechanic has not been49exercised live in this session** — whether an MCP connector's staging flow can actually carry a50`FileContract` payload (vs. only reading/renaming/reassigning existing icons) is unconfirmed. Until51verified, treat *uploading a new file* as something to do in the Software Factory's own Icons52repository UI, and use the API confidently for everything else here: reading, grouping, tagging,53renaming, decolorizing, consolidating (`task_update_icon_usage`), and assigning an existing `icon_id`54to any of the fields below.5556## Every verified assignment point5758Confirmed by pulling the full property list of every candidate entity against the live domain (not just59`icon`'s own reverse navigation, which misses one real case below) — this is the complete set of60entities that carry an icon-referencing field, not a curated subset.6162**Almost every one of them carries a pair, not a single field**: an `<x>icon_id` (or `image_id` on63`cube_view_field_conditional_layout`) that's a foreign key into the shared `icon` repository, *and* its64own local `<x>icon`/`<x>icon_data` (`SQLSERVER_SF.FileContract` + `Edm.Binary`) that uploads a file65straight onto that row, bypassing the repository entirely. Both are always present or absent together,66with **one verified exception**: `tab_task` has *only* the local `icon`/`icon_data` pair — a67table-specific task icon override can never be picked from the shared repository, only uploaded fresh68onto that one `tab_task` row.6970**Prefer the `_id` repository field whenever both exist.** The local `icon`/`icon_data` pair is a71parallel, older upload mechanism — it works, but an icon set that way doesn't show up in the shared72repository for reuse, can't be redirected via `task_update_icon_usage`, and won't benefit from73`task_enrichment_decolorize_svg` being run once and shared everywhere. Reach for it only where there is74no `_id` alternative (`tab_task`) or the user explicitly wants a one-off asset kept out of the shared75repository.7677| Object | Repository field | Local-upload field(s) | What it controls |78|---|---|---|---|79| `branch` | `icon_id` | `icon`/`icon_data` | The branch's own icon (design-time — shown wherever a branch is picked/listed, not necessarily an end-user surface). |80| `tab` | `icon_id` | `icon`/`icon_data` | A table/view's icon — its document, menu item, and detail navigation. |81| `tab_variant_overview` | `icon_id` | `icon`/`icon_data` | Per-variant override of a table's icon. |82| `task` | `icon_id` | `icon`/`icon_data` | A task's icon — action bars, menus, wherever the task appears. |83| `task_variant_overview` | `icon_id` | `icon`/`icon_data` | Per-variant override of a task's icon. |84| `tab_task` | *(none)* | `icon`/`icon_data` only | A table-specific override of a task's icon for one table's action bar — **upload-only, no repository option**, verified live. |85| `report` | `icon_id` | `icon`/`icon_data` | A report's icon. |86| `report_variant_overview` | `icon_id` | `icon`/`icon_data` | Per-variant override of a report's icon. |87| `tab_prefilter` | `icon_id` | `icon`/`icon_data` | A single prefilter's icon. |88| `tab_prefilter_grp` | `icon_id` | `icon`/`icon_data` | A prefilter group's icon. |89| `menu` | `icon_id` | `icon`/`icon_data` | The whole menu's icon (shown when switching between menus). |90| `list_bar_grp` | `icon_id` | `icon`/`icon_data` | A list-bar menu group's icon. Weak entity — its edit key is `(model_id, branch_id, menu_id, list_bar_grp_id)`, not `list_bar_grp_id` alone; see `thinkwise_software_factory_mcp_base` on weak-entity edit keys. |91| `tile_grp` | `icon_id` | `icon`/`icon_data` | A tile group's icon. |92| `module_grp` | `icon_id` | `icon`/`icon_data` | A legacy tree menu's module-group icon. |93| `tab_task_grp` | `icon_id` | `icon`/`icon_data` | A table action-bar task-group icon. |94| `tab_report_grp` | `icon_id` | `icon`/`icon_data` | A table action-bar report-group icon. |95| `cube_view` | `cube_view_icon_id` | `cube_view_icon`/`cube_view_icon_data` | A cube view's icon (e.g. on a BI menu/tile). |96| `msg_option` | `icon_id` | `icon`/`icon_data` | A modeled message's option button (confirm/retry/cancel-style choices) — see `thinkwise_software_factory_messages`. |97| `elemnt` | `icon_id` | `icon`/`icon_data` | A single domain element's (enum value's) icon — renders when the owning `dom.control_id` is set to an icon-based control (an image/icon combo or radio-style presentation), not for a plain text/combo domain. |98| `cube_view_field_conditional_layout` | `image_id` (confirmed FK into `icon.icon_look_up`, same repository, just named "image") | `image`/`image_data` | An icon-based conditional layout — showing an icon instead of/alongside color for a computed condition. See `thinkwise_software_factory_conditional_layouts` and `thinkwise_software_factory_cubes`. |99| `screen_component` | `tab_page_icon_id` | `tab_page_icon`/`tab_page_icon_data` | A custom screen component's tab-page icon (multi-page custom components). `screen_component_type_icon`/`_data` also exists but is the component *type's* own icon, not settable per instance. |100| `col` | `form_next_grp_icon_id`, `next_tab_icon_id` | matching `form_next_grp_icon`/`_data`, `next_tab_icon`/`_data` | A column's "jump to related form group" / "jump to related tab" navigation icons. |101| `report_parmtr` | same two `_id` fields | same local pairs | Same navigation-icon pattern, on a report parameter. |102| `task_parmtr` | same two `_id` fields | same local pairs | Same navigation-icon pattern, on a task parameter. |103| `tab_variant_form_overview` | same two `_id` fields | same local pairs | Per-variant override of a table column's navigation icons. |104| `report_variant_form_overview` | same two `_id` fields | same local pairs | Per-variant override of a report parameter's navigation icons. |105| `task_variant_form_overview` | same two `_id` fields | same local pairs | Per-variant override of a task parameter's navigation icons. |106107Notably **absent**: `tile` and `list_bar_item` carry no icon field of their own at all — a menu item108always shows the icon of whatever it points to (`tab`/`report`/`task`, or that object's variant109override), confirming the platform's own "menu item icon = referenced object's icon" convention rather110than a separate menu-only vocabulary. `action_bar` likewise carries no icon field — per-action display111(icon-only vs. icon+text vs. overflow) is controlled by `action_bar`'s own `default_display_type` enum112(`icon_text_*`/`text_only_*`/`icon_only_*`/`overflow`/`hidden` values, verified live), not by a separate113icon field. `task_button`/`report_button` were checked directly and don't exist as entity sets in this114domain at all.115116## Assigning or changing an icon117118Whenever a skill or task involves creating or configuring any object in the table above (a table, a119task, a report, a prefilter, a menu/group, a cube view, a domain element on an icon-capable domain, a120message option, a form/report navigation group, an icon-based conditional layout), **assigning it a121suitable icon is part of finishing that object, not an optional extra** — don't leave the field unset122by default just because the field itself isn't mandatory — **unless the model's existing convention for123that exact object type says otherwise (step 0 below).**1241250. **Follow the model's existing convention for this object type — don't impose one.** Before assigning126 an icon to a *newly created* object, check how existing rows of that same entity (e.g. other127 `list_bar_grp` rows on the same or other menus, other `menu` rows, other `tab_prefilter_grp` rows)128 actually use the field: count how many have the `_id`/local-upload field set vs. null.129 - If existing rows overwhelmingly **do** use icons, assign one to the new object too (proceed with130 steps 1+ below).131 - If existing rows overwhelmingly **don't** use icons (e.g. a model has several `list_bar_grp` rows132 and none of them carry an icon), **don't** add one to the new object either — match the model's133 established look rather than making one object inconsistent with its peers. Say so explicitly134 ("this model's existing menu groups don't use icons, so I'm leaving this one unset to match") rather135 than silently skipping it.136 - If usage is mixed with no clear majority, or there are no existing rows of that type to compare137 against (this is the first one), fall back to the default in the paragraph above: assign an icon.138 - Judge this **per object type**, not globally — a model can consistently iconify `tab` rows while139 never iconifying `list_bar_grp` rows; don't let one type's convention decide another's.1401. **Reuse before uploading.** Query `icon` (optionally filtered by `icon_grp_id`/`icon_tag`) for an141 existing icon matching the concept before creating a new one — see142 `references/icon_selection_guide.md` for how to judge "matching."1432. **If nothing in the repository fits, don't upload or pick unilaterally — ask the user.** Present144 what you searched for and why nothing matched, then ask (via `AskUserQuestion` or a plain question)145 whether they want to (a) upload a specific icon file themselves for you to add to the repository, or146 (b) name a specific existing icon (even an imperfect fit) to use instead. This mirrors147 `thinkwise_software_factory_maps_component`'s existing rule for `elemnt.icon` — don't silently pick a148 "close enough" icon or leave the field blank when no confident match exists.1493. Set the target field to the chosen `icon_id` (repository) via `patch_resource`/`stage_resource` —150 prefer the `_id` field over the entity's own local `icon`/`icon_data` upload pair wherever both exist151 (see "Prefer the `_id` repository field" above); use the local pair only on `tab_task`, where it's the152 only option, or when the user explicitly wants a one-off file kept out of the shared repository.1534. **Before changing an icon that's already assigned elsewhere**, check whether other objects share it —154 an unrelated screen can shift visually if you edit or replace a widely-reused icon. Prefer155 `task_update_icon_usage` (redirect *this* object's assignment to a different, more specific icon by156 changing the field directly; use the task only when you actually want to repoint *every* usage of one157 icon at once, e.g. consolidating duplicates).1585. Per `thinkwise_software_factory_mcp_base`'s confirm-before-mutate rule: state which icon (existing or159 new) you're assigning and why before the first mutating call, especially for a menu/table/task icon160 that's user-visible across the whole application, not just a low-stakes internal object.1616. **After setting `dom.control_id` to an icon-capable control** (e.g. `IMAGE_COMBO`) so `elemnt.icon_id`162 will actually render: if the domain's underlying data type is numeric (`SMALLINT`/tinyint/etc.), the163 Software Factory silently resets `dom.alignment` to `right` (1) as a side effect of the control_id164 change — even though a left-aligned icon/enum-style presentation is what you actually want. Confirmed165 live: setting `control_id=IMAGE_COMBO` on 4 numeric domains flipped all 4 to `alignment=1`, while166 sibling element-bearing domains in the same model that hadn't had their control_id touched stayed at167 `alignment=0` (left). Re-read `dom.alignment` right after any `control_id` write on a numeric domain168 and patch it back to `left` (numeric value `0` — the string key `"left"` is rejected with169 `invalid_input`) unless the model's own convention for that domain type is actually right-aligned.170171## Auditing a model for missing icons172173When asked to find every icon field that's currently unset — rather than assigning icons for objects174already being built — don't treat every null `*icon_id`/`image_id` as a gap to fill. Several of the175fields in the table above are optional per-row overrides for a feature that many models never turn on,176so they're null by design, not by omission:177178- **Navigation icons** (`col`/`report_parmtr`/`task_parmtr`/`*_variant_form_overview`'s179 `form_next_grp_icon_id`/`next_tab_icon_id`) only render when that column/parameter actually has the180 matching jump-to-group/jump-to-tab navigation configured. If no row in the model uses that181 navigation feature at all, leave these alone.182- **`elemnt.icon_id`** only renders when the owning `dom.control_id` is an icon-capable control (see183 the pre-flight checklist below) — a domain element on a plain `COMBO`/text control never displays it.184- **`screen_component.tab_page_icon_id`** only matters for a multi-page custom screen component — a185 single-page component (or a model with no multi-page custom components at all) leaves it null186 meaningfully.187- **`tab_task`'s local `icon`/`icon_data` override** only matters where a table actually overrides one188 of its tasks' icons for its own action bar — most tables never do, so an empty value there isn't a189 gap.190191Before flagging any of these as "missing," check whether the underlying feature is used anywhere in192the model at all (e.g. count rows where the relevant field is *set*, not just where it's null) — a193feature sitting at zero usage means there's nothing to iconify, not several fields to fill in.194195## Pre-flight checklist196197- Confirmed connector/model/branch per `thinkwise_software_factory_mcp_base`.198- For a *newly created* object, checked whether existing rows of that same entity commonly use icons199 before assigning (or skipping) one — matched the model's existing convention per object type rather200 than defaulting to always-on; only defaulted to assigning when usage was mixed or there was no201 existing row to compare against. See "Follow the model's existing convention" (step 0) above.202- Searched the existing `icon`/`icon_grp`/`icon_tag` repository for a matching concept before proposing203 a new upload.204- Picked the *specific* field for the object at hand from the table above — note several entities have205 **two** variant-scoped fields (base `*_overview` vs. the plain entity), the two navigation-icon fields206 (`form_next_grp_icon_id` vs. `next_tab_icon_id`) are visibly different UI hooks, and most objects have207 **both** a repository `_id` field and a local `icon`/`icon_data` upload pair — used the `_id` field208 unless the object is `tab_task` (upload-only) or the user wants a one-off asset.209- If no existing icon in the repository fit, asked the user to upload one or name a specific icon,210 rather than picking the closest match unilaterally or leaving the field unset.211- For a status/enum-driven icon, checked that the owning `dom.control_id` is actually an icon-capable212 control before setting `elemnt.icon_id` — on a plain text/dropdown domain the field would go unused.213- After setting `dom.control_id` on a numeric-typed domain, re-checked `dom.alignment` and reset it to214 `left` if the Software Factory silently flipped it to `right` (see step 6 above) — don't assume215 alignment is untouched by a control_id change.216- Read `references/icon_selection_guide.md`'s relevant section (action/object/status/menu/prefilter/217 report/form-group) before picking the concept, not just the mechanical field.218- Before replacing or heavily editing a shared icon, checked its other assignments; used219 `task_update_icon_usage` for a genuine one-to-many consolidation rather than hand-editing every field.220- New-file upload not yet verified via this API — routed actual file uploads through the Software221 Factory's own Icons repository UI unless/until confirmed otherwise.222- If auditing an existing model for missing icons (not authoring new objects), confirmed the223 underlying optional feature (nav icons, multi-page screen components, per-table task icon224 overrides) is actually used before treating a null field as a gap — see "Auditing a model for225 missing icons" above.