Extract 55 knowledge articles from BC review-agent prompt

Adds 55 articles (plus 76 code samples) spanning four new domains and
two existing domains, extracted from the internal Business Central
review-agent prompt. Content was filtered against BCQuality's
remedial-knowledge premise: each article encodes BC-specific behaviour,
a CodeCop rule, a platform API semantic, or an anti-false-positive
guideline that a capable LLM would otherwise get wrong.

New domains:
- privacy (11 articles): DataClassification inheritance semantics, the
  StrSubstNo-defeats-Error-telemetry-classification pitfall, Privacy
  Notice consent for outgoing requests, anti-false-positives for pages
  and in-memory data.
- upgrade (11 articles): upgrade-codeunit structure, upgrade-tag
  lifecycle and registration, protected DB reads, DataTransfer for
  large datasets, InitValue semantics, enum-ordinal preservation,
  obsolete-workflow, first-install detection.
- ui (9 articles): caption capitalization by phrase type, tooltip voice,
  teaching-tip vs tooltip, tour-tip conventions, character limits,
  banned terms, ampersand handling, title punctuation.
- style (11 articles): label-suffix convention, API page naming,
  temporary-variable prefix, label properties (Comment/Locked), named
  invocations, FieldCaption in user messages, OptionCaption pairing,
  Error-parameter passing, `this` keyword, required parentheses, file
  naming.

Gaps in existing domains:
- performance (11 articles): production-scale table catalog (no row
  counts, per internal-data concern), anti-false-positive for bounded
  tables, guard-before-Get ordering, redundant-Get-in-OnAfterGetRecord,
  LockTable in read-only helpers, combined ModifyAll passes, writes in
  OnAfterGetRecord, SetLoadFields heuristics, temporary-table
  regressions, FlowField source-table widening, MaintainSQLIndex
  disabling SIFT.
- security (2 articles): environment-specific hardcoded GUIDs,
  ValidateTableRelation=false on user input.

Intentionally excluded: specific production P95 row-count numbers
(aggregated internal telemetry); rewritten as categorical guidance on
which tables to treat as production-scale without publishing sizes.

All articles use `bc-version: [all]` (applies to every BC version, per
the new schema sentinel). Validator passes with 0 errors / 0 warnings.
This commit is contained in:
Jesper Schulz-Wedde 2026-04-23 16:43:42 +02:00
parent 9a4198eb28
commit e570d6113f
131 changed files with 2799 additions and 0 deletions

View file

@ -0,0 +1,26 @@
page 51005 "UI Sample ActionTooltip Bad"
{
PageType = Card;
SourceTable = "Sales Header";
actions
{
area(Processing)
{
action(Post)
{
Caption = 'Post';
ApplicationArea = All;
// Declarative, not imperative. No period.
ToolTip = 'This will post the invoice';
}
action(SendForApproval)
{
Caption = 'Send for approval';
ApplicationArea = All;
// Fragment that repeats the caption and says nothing new.
ToolTip = 'Send for approval';
}
}
}
}

View file

@ -0,0 +1,25 @@
page 51004 "UI Sample ActionTooltip Good"
{
PageType = Card;
SourceTable = "Sales Header";
actions
{
area(Processing)
{
action(Post)
{
Caption = 'Post';
ApplicationArea = All;
// Imperative verb-first sentence, Sentence case, terminating period.
ToolTip = 'Post the current sales invoice and finalize the transaction.';
}
action(SendForApproval)
{
Caption = 'Send for approval';
ApplicationArea = All;
ToolTip = 'Send the document to the approval workflow.';
}
}
}
}

View file

@ -0,0 +1,26 @@
---
bc-version: [all]
domain: ui
keywords: [tooltip, action, imperative, voice, period]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Action tooltips are imperative, verb-first sentences ending with a period
## Description
Action tooltips describe what the user will cause by invoking the action. The house style is an imperative verb-first sentence — `Post the current sales invoice and finalize the transaction.` — not a declarative one ("This will post …") and not a fragment ("Post invoice"). The imperative voice matches how the user reads the action bar: each tooltip completes the sentence "If I click this, the system will …" in the same grammatical form. Shortcut-key hints, when present, belong at the end of the tooltip and are retained verbatim.
## Best Practice
Start the tooltip with the verb. Use Sentence case, end with a period, stay within the ~250-character budget. Keep one sentence unless the action genuinely needs two; avoid editorializing ("Easily post …") or narrating ("This action posts …"). Preserve any existing shortcut annotation.
See sample: `action-tooltips-are-imperative-and-end-with-period.good.al`.
## Anti Pattern
`ToolTip = 'This will post the invoice'` — declarative rather than imperative, no period. `ToolTip = 'Post'` — one-word fragment that duplicates the Caption and says nothing new. Both fail the scan-the-action-bar comprehension test.
See sample: `action-tooltips-are-imperative-and-end-with-period.bad.al`.

View file

@ -0,0 +1,22 @@
---
bc-version: [all]
domain: ui
keywords: [terminology, disabled, invalid, whitelist, blacklist, voice]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Avoid banned UI terms; prefer the inclusive and direct replacements
## Description
Business Central's UI voice guidelines exclude four terms that carry connotations the product does not want to push onto users: "Disabled" (clinical/negative), "Invalid" (pejorative), "Whitelist" and "Blacklist" (terms with racial associations the industry has moved away from). The replacements read naturally, match the product's warm-and-direct voice, and align with Microsoft's cross-product terminology. The concern applies to user-visible text — captions, tooltips, error messages, notifications — not to variable names or code comments.
## Best Practice
Replace "Disabled" with "Turned off" or "Not available". Replace "Invalid" with "Not valid" or "Incorrect". Replace "Whitelist" with "Allow list". Replace "Blacklist" with "Block list". Apply the substitution in all UI text surfaces: Caption, ToolTip, AboutTitle, AboutText, Label values, Message/Confirm/Error strings.
## Anti Pattern
`ErrorLbl: Label 'Invalid input.'`, `Caption = 'Disabled Users'`, `ToolTip = 'Specifies the blacklist of blocked senders.'` — all three terms in places the user will read. The fix is literal substitution with the approved alternative.

View file

@ -0,0 +1,21 @@
page 51001 "UI Sample Caption Bad"
{
PageType = List;
SourceTable = Customer;
// Noun phrase in Sentence case. Every other list page in the product is Title Case.
Caption = 'Sales orders';
actions
{
area(Processing)
{
// Sentence phrase in Title Case. Reads as a typo.
action(PostAndPrint)
{
Caption = 'Post And Print';
ApplicationArea = All;
}
}
}
}

View file

@ -0,0 +1,27 @@
page 51000 "UI Sample Caption Good"
{
PageType = List;
SourceTable = Customer;
// Noun-phrase page caption: Title Case.
Caption = 'Sales Orders';
actions
{
area(Processing)
{
// Sentence-phrase action caption: Sentence case.
action(PostAndPrint)
{
Caption = 'Post and print';
ApplicationArea = All;
}
action(SendEmail)
{
Caption = 'Send email';
ApplicationArea = All;
}
}
}
}

View file

@ -0,0 +1,26 @@
---
bc-version: [all]
domain: ui
keywords: [caption, capitalization, title-case, sentence-case, noun-phrase]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Capitalize captions by phrase type: noun phrase is Title Case, sentence phrase is Sentence case
## Description
Business Central UI captions follow a simple capitalization rule that depends on the grammatical shape of the caption, not its location. A caption that is a pure noun phrase — no verb — uses Title Case: each major word capitalized (`Sales Orders`, `Chart of Accounts`, `Payment Terms`). A caption that is an imperative or declarative sentence phrase — contains a verb — uses Sentence case: only the first word and proper nouns capitalized (`Post and print`, `Send email`, `Create flow`). Following the rule makes unrelated captions feel consistent; ignoring it is visibly inconsistent in the user's navigation.
## Best Practice
Decide by parsing the caption as a phrase. "Sales Orders" is a thing; Title Case. "Post and print" tells the user to do something; Sentence case. For captions that are literally a single noun (`Save`, `Close`), treat them as sentence phrases — the imperative verb is implied.
See sample: `caption-capitalization-noun-phrase-vs-sentence-phrase.good.al`.
## Anti Pattern
Writing `Caption = 'Sales orders'` on a list page (noun phrase styled as a sentence) or `Caption = 'Post And Print'` on an action (sentence phrase styled as title case). Both read as typos to a native English reader and inconsistent to a translator.
See sample: `caption-capitalization-noun-phrase-vs-sentence-phrase.bad.al`.

View file

@ -0,0 +1,26 @@
page 51003 "UI Sample FieldTooltip Bad"
{
PageType = Card;
SourceTable = Customer;
layout
{
area(Content)
{
group(General)
{
field("Name"; Rec.Name)
{
ApplicationArea = All;
// No "Specifies" opener, no period, a bare fragment.
ToolTip = 'The name of the customer';
}
field("Balance (LCY)"; Rec."Balance (LCY)")
{
ApplicationArea = All;
ToolTip = 'Balance';
}
}
}
}
}

View file

@ -0,0 +1,25 @@
page 51002 "UI Sample FieldTooltip Good"
{
PageType = Card;
SourceTable = Customer;
layout
{
area(Content)
{
group(General)
{
field("Name"; Rec.Name)
{
ApplicationArea = All;
ToolTip = 'Specifies the name of the customer.';
}
field("Balance (LCY)"; Rec."Balance (LCY)")
{
ApplicationArea = All;
ToolTip = 'Shows the current balance in the local currency.';
}
}
}
}
}

View file

@ -0,0 +1,26 @@
---
bc-version: [all]
domain: ui
keywords: [tooltip, field, specifies, voice, period]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Field tooltips start with "Specifies" and end with a period
## Description
Field tooltips describe what a value means, and the Business Central house style for them is a declarative sentence that starts with "Specifies" and ends with a period. The convention is not cosmetic: it yields a consistent voice across thousands of fields so a user scanning several tooltips in quick succession can compare them without re-parsing each opening clause. Alternative phrasings ("Shows …", "The …") are accepted when they describe the field clearly, but "Specifies …" is the default and the easiest to translate consistently.
## Best Practice
Write field tooltips as `Specifies <what the field represents>.` — a single sentence, Sentence case, terminating period. Keep under the ~250-character tooltip budget (see `respect-ui-text-character-limits`). When the field's meaning is genuinely not a "specifies" sentence, use "Shows …" or a clearly descriptive alternative; avoid bare fragments.
See sample: `field-tooltips-start-with-specifies-and-end-with-period.good.al`.
## Anti Pattern
`ToolTip = 'The name of the customer'` — missing "Specifies" opener, missing period. `ToolTip = 'Customer name'` — a fragment rather than a sentence. Both sit inconsistently next to adjacent "Specifies …" tooltips on the same page.
See sample: `field-tooltips-start-with-specifies-and-end-with-period.bad.al`.

View file

@ -0,0 +1,22 @@
---
bc-version: [all]
domain: ui
keywords: [caption, tooltip, character-limit, truncation, localization]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Respect Business Central's UI text character limits to avoid truncation
## Description
Business Central UI surfaces have practical character limits before the platform truncates or the translator's localization overflows the available space. Authoring captions and tooltips close to the English limit almost guarantees truncation in languages whose translations are longer (German, French, Spanish average 2040% longer than English). The limits are not hard compiler errors — they are product-quality thresholds that agents should flag at author time so the string reaches localization with room to grow.
## Best Practice
Author within these approximate limits (English): action and field captions ~40 chars; field-group, menu-item, page, and dialog titles ~40 chars; button captions ~20 chars; action and field tooltips ~250 chars; dialog text and error messages ~250 chars; notifications ~100 chars; checklist ShortTitleChecklist 34, LongerTitleCard 53, CardDescription 180. Leave headroom for longer translations; at 40/40 in English, German is likely to truncate.
## Anti Pattern
`action(RecalculateAndReapplyAllOutstandingCustomerDiscounts) { Caption = 'Recalculate and reapply all outstanding customer discounts'; }` — 58 characters in English, essentially guaranteed to truncate once translated. The fix is to shorten the English caption (`Recalculate customer discounts`, 30 chars) and move the full sentence into the tooltip where the budget is larger.

View file

@ -0,0 +1,22 @@
---
bc-version: [all]
domain: ui
keywords: [title, caption, page, dialog, punctuation, ellipsis]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Titles carry no trailing punctuation and no trailing ellipsis
## Description
Page titles, section titles, FastTab titles, and dialog titles in Business Central are labels, not sentences — they have no trailing period, question mark, or exclamation. Trailing ellipsis ("…" or "...") on a title is specifically a long-standing Windows convention for action buttons that open a dialog, and AL handles that via the action's runtime behaviour rather than the caption text. Adding the ellipsis literally into a page caption or action caption is wrong in both directions: the platform also displays its own ellipsis when appropriate, and the static three dots corrupt translations that adjust punctuation for the locale.
## Best Practice
End titles with the last word of the title. Sentence case per the capitalization rule for the phrase type (see `caption-capitalization-noun-phrase-vs-sentence-phrase`). If a dialog needs "…" behaviour, rely on the platform; do not type the characters into the caption string.
## Anti Pattern
`Caption = 'Setup wizard...'`, `Caption = 'Sales orders.'`, `page Caption = 'Customer list:'` — all three decorate the title with terminal punctuation that is noise to the reader and a translation headache.

View file

@ -0,0 +1,22 @@
---
bc-version: [all]
domain: ui
keywords: [tooltip, teaching-tip, abouttitle, abouttext, onboarding]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Tooltips describe what a thing is; teaching tips guide what the user can do with it
## Description
Business Central exposes two distinct affordances for explaining the UI: ToolTip and the AboutTitle/AboutText teaching tip. They answer different questions and are complementary, not alternatives. ToolTip answers "What is this field/action?" and is expected on every field and action. The teaching tip answers "What can I do with this page or this important element?" and is reserved for the few entry points where an onboarding hint is worth the user's attention. Authors who put teaching-tip content in tooltips make tooltips noisy; authors who put tooltip content in teaching tips make teaching tips useless.
## Best Practice
Write ToolTip as a concise descriptive sentence following the "Specifies …" or imperative voice rules. Reserve AboutTitle/AboutText for the top-level card and list pages where first-time users benefit from discovering the page's purpose and outcome. On list pages, title uses the plural form ("About sales invoices"). On card or document pages, title uses the entity name plus "details" ("About sales invoice details").
## Anti Pattern
A field ToolTip that tells the user "You can create new customers from here and update their payment terms, and the list also shows…" — that is teaching-tip content. Conversely, an AboutText that simply repeats the page Caption tells the user nothing they did not already read in the title bar.

View file

@ -0,0 +1,22 @@
---
bc-version: [all]
domain: ui
keywords: [tour-tip, abouttext, teaching-tip, imperative, onboarding]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Tour tips describe outcomes, not instructions — never tell the user to perform an action during the tour
## Description
A tour is a guided sequence of teaching tips that runs over the page while the user is passively watching. The tour framework does not expose the page's actions during the tip — so an `AboutText` that tells the user `Enter the customer name here.` or `Now post the invoice.` asks the user to do something that is not possible in the moment. The result is a confusing first-run experience. Tour content should describe what the element represents and what the user will be able to do with it after the tour completes, in descriptive rather than imperative voice.
## Best Practice
Write tour AboutTitle as a short noun-phrase label for the element ("Who you are selling to", "When all is set, you post"). Write AboutText as one or two sentences that describe the outcome or meaning, not steps. Keep the tour itself short — one to four tips total — and let the regular ToolTip carry the per-element detail.
## Anti Pattern
`AboutText = 'Enter the customer name here.'` on a tour tip — the action is not active. `AboutText = 'Now post the invoice.'` during a tour — the user cannot, and would not want to mid-tour. Both teach nothing and confuse the reader.

View file

@ -0,0 +1,20 @@
page 51007 "UI Sample Ampersand Bad"
{
PageType = Card;
SourceTable = "Sales Header";
actions
{
area(Processing)
{
action(PostAndSend)
{
// '&' is being used as "and", not as an accelerator prefix. The
// parser cannot tell; translators re-evaluate every occurrence.
Caption = 'Post & Send';
ApplicationArea = All;
ToolTip = 'Post and send the document.';
}
}
}
}

View file

@ -0,0 +1,19 @@
page 51006 "UI Sample Ampersand Good"
{
PageType = Card;
SourceTable = "Sales Header";
actions
{
area(Processing)
{
action(PostAndSend)
{
// "and" written out. Ampersand-s marks 's' as the accelerator key.
Caption = 'Post and &send';
ApplicationArea = All;
ToolTip = 'Post the document and send it to the customer.';
}
}
}
}

View file

@ -0,0 +1,26 @@
---
bc-version: [all]
domain: ui
keywords: [ampersand, caption, accelerator, translation, voice]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Write "and" in UI captions; keep the ampersand only as an accelerator-key prefix
## Description
AL Caption strings use the ampersand character in two distinct ways. Inside a caption, `&` is the accelerator-key prefix — `Caption = '&Post'` underlines the P and makes Alt+P activate the action. Outside that role, `&` is sometimes used as a shortening for the word "and" (`Post & Send`). The first usage is platform-defined and must be preserved. The second is a style choice that the Business Central voice guidelines reject: `Post and send` reads naturally in all supported locales and translates cleanly, while `Post & Send` conveys nothing extra and adds a character that localizers have to re-evaluate.
## Best Practice
Use the word "and" in caption text. Keep `&` only when it is immediately followed by a letter chosen as the keyboard accelerator. If both meanings apply, write them explicitly: `Post and &send` uses `s` as the accelerator and spells the conjunction out.
See sample: `use-and-not-ampersand-in-ui-captions.good.al`.
## Anti Pattern
`Caption = 'Post & Send'` as the full caption — the ampersand is meant as "and" but the AL parser cannot tell, and the result is inconsistent with every other "X and Y" caption in the product.
See sample: `use-and-not-ampersand-in-ui-captions.bad.al`.