Fix knowledge corpus integrity issues

Repair broken knowledge references and align review examples with canonical articles. Correct explicit version gates, restore a missing title, and recognize the plugin directory in the root guard.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-07-10 12:46:43 +02:00
parent 3aa3581f95
commit a56d1453b9
15 changed files with 58 additions and 65 deletions

View file

@ -127,36 +127,36 @@ Output conforms to the DO output contract, extended with `sub-results` and `skip
},
"findings": [
{
"id": "microsoft/knowledge/performance/filter-before-find.md",
"id": "microsoft/knowledge/performance/apply-filters-before-iterating.md",
"severity": "major",
"message": "FindSet is called on a record variable without any prior SetRange/SetFilter. This forces a full-table scan.",
"message": "The Country/Region Code predicate is evaluated inside the loop instead of with SetRange before FindSet, so every row crosses the database boundary.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 140,
"range": { "start-line": 140, "end-line": 144 }
},
"references": [
{ "path": "microsoft/knowledge/performance/filter-before-find.md" }
{ "path": "microsoft/knowledge/performance/apply-filters-before-iterating.md" }
],
"confidence": "high",
"from-sub-skill": "al-performance-review"
},
{
"id": "community/knowledge/performance/call-setloadfields-before-filters.md",
"id": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md",
"severity": "minor",
"message": "SetLoadFields is called after SetRange. Per the referenced guidance the call must come before filters to be folded into the query plan.",
"message": "The loop reads an unlisted field after SetLoadFields, triggering a hidden JIT load for each record passed by value.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 152
},
"references": [
{ "path": "community/knowledge/performance/call-setloadfields-before-filters.md" }
{ "path": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md" }
],
"confidence": "high",
"from-sub-skill": "al-performance-review"
},
{
"id": "microsoft/knowledge/security/use-secrettext-for-credentials.md",
"id": "microsoft/knowledge/security/secrettext-for-credentials.md",
"severity": "blocker",
"message": "A bearer token is declared as a Text parameter and passed through the HTTP request path as plain text. The referenced guidance requires credentials to flow as SecretText end-to-end.",
"location": {
@ -165,21 +165,21 @@ Output conforms to the DO output contract, extended with `sub-results` and `skip
"range": { "start-line": 85, "end-line": 89 }
},
"references": [
{ "path": "microsoft/knowledge/security/use-secrettext-for-credentials.md" }
{ "path": "microsoft/knowledge/security/secrettext-for-credentials.md" }
],
"confidence": "high",
"from-sub-skill": "al-security-review"
},
{
"id": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md",
"id": "community/knowledge/security/secrets-isolated-storage.md",
"severity": "minor",
"message": "An API key is assigned from a string literal rather than retrieved from IsolatedStorage or Key Vault at runtime.",
"message": "A setup table stores an API key in an ordinary Text field, exposing it through table reads and exports. Persist it in IsolatedStorage instead.",
"location": {
"file": "src/Integration/ApiClient.Codeunit.al",
"line": 201
"file": "src/Integration/ExternalServiceSetup.Table.al",
"line": 12
},
"references": [
{ "path": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md" }
{ "path": "community/knowledge/security/secrets-isolated-storage.md" }
],
"confidence": "medium",
"from-sub-skill": "al-security-review"
@ -209,29 +209,29 @@ Output conforms to the DO output contract, extended with `sub-results` and `skip
},
"findings": [
{
"id": "microsoft/knowledge/performance/filter-before-find.md",
"id": "microsoft/knowledge/performance/apply-filters-before-iterating.md",
"severity": "major",
"message": "FindSet is called on a record variable without any prior SetRange/SetFilter. This forces a full-table scan.",
"message": "The Country/Region Code predicate is evaluated inside the loop instead of with SetRange before FindSet, so every row crosses the database boundary.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 140,
"range": { "start-line": 140, "end-line": 144 }
},
"references": [
{ "path": "microsoft/knowledge/performance/filter-before-find.md" }
{ "path": "microsoft/knowledge/performance/apply-filters-before-iterating.md" }
],
"confidence": "high"
},
{
"id": "community/knowledge/performance/call-setloadfields-before-filters.md",
"id": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md",
"severity": "minor",
"message": "SetLoadFields is called after SetRange. Per the referenced guidance the call must come before filters to be folded into the query plan.",
"message": "The loop reads an unlisted field after SetLoadFields, triggering a hidden JIT load for each record passed by value.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 152
},
"references": [
{ "path": "community/knowledge/performance/call-setloadfields-before-filters.md" }
{ "path": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md" }
],
"confidence": "high"
}
@ -247,7 +247,7 @@ Output conforms to the DO output contract, extended with `sub-results` and `skip
},
"findings": [
{
"id": "microsoft/knowledge/security/use-secrettext-for-credentials.md",
"id": "microsoft/knowledge/security/secrettext-for-credentials.md",
"severity": "blocker",
"message": "A bearer token is declared as a Text parameter and passed through the HTTP request path as plain text. The referenced guidance requires credentials to flow as SecretText end-to-end.",
"location": {
@ -256,20 +256,20 @@ Output conforms to the DO output contract, extended with `sub-results` and `skip
"range": { "start-line": 85, "end-line": 89 }
},
"references": [
{ "path": "microsoft/knowledge/security/use-secrettext-for-credentials.md" }
{ "path": "microsoft/knowledge/security/secrettext-for-credentials.md" }
],
"confidence": "high"
},
{
"id": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md",
"id": "community/knowledge/security/secrets-isolated-storage.md",
"severity": "minor",
"message": "An API key is assigned from a string literal rather than retrieved from IsolatedStorage or Key Vault at runtime.",
"message": "A setup table stores an API key in an ordinary Text field, exposing it through table reads and exports. Persist it in IsolatedStorage instead.",
"location": {
"file": "src/Integration/ApiClient.Codeunit.al",
"line": 201
"file": "src/Integration/ExternalServiceSetup.Table.al",
"line": 12
},
"references": [
{ "path": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md" }
{ "path": "community/knowledge/security/secrets-isolated-storage.md" }
],
"confidence": "medium"
}
@ -310,4 +310,3 @@ The empty-corpus case — BCQuality's state until knowledge files land — rolls
]
}
```

View file

@ -89,29 +89,29 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/performance/filter-before-find.md",
"id": "microsoft/knowledge/performance/apply-filters-before-iterating.md",
"severity": "major",
"message": "FindSet is called on a record variable without any prior SetRange/SetFilter. This forces a full-table scan.",
"message": "The Country/Region Code predicate is evaluated inside the loop instead of with SetRange before FindSet, so every row crosses the database boundary.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 140,
"range": { "start-line": 140, "end-line": 144 }
},
"references": [
{ "path": "microsoft/knowledge/performance/filter-before-find.md" }
{ "path": "microsoft/knowledge/performance/apply-filters-before-iterating.md" }
],
"confidence": "high"
},
{
"id": "community/knowledge/performance/call-setloadfields-before-filters.md",
"id": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md",
"severity": "minor",
"message": "SetLoadFields is called after SetRange. Per the referenced guidance the call must come before filters to be folded into the query plan.",
"message": "The loop reads an unlisted field after SetLoadFields, triggering a hidden JIT load for each record passed by value.",
"location": {
"file": "src/Sales/PostingRoutines.Codeunit.al",
"line": 152
},
"references": [
{ "path": "community/knowledge/performance/call-setloadfields-before-filters.md" }
{ "path": "community/knowledge/performance/setloadfields-unlisted-field-triggers-jit-load.md" }
],
"confidence": "high"
}
@ -134,4 +134,3 @@ The empty-corpus case — BCQuality's state until performance knowledge files la
"suppressed": []
}
```

View file

@ -89,16 +89,16 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/privacy/strsubstno-prebuild-breaks-error-telemetry-classification.md",
"id": "microsoft/knowledge/privacy/data-classification-required-on-pii-fields.md",
"severity": "major",
"message": "Error receives a pre-built Text produced by StrSubstNo with customer name and email as arguments. Per the referenced guidance the platform cannot classify or strip PII from an opaque Text and will export the full message to telemetry.",
"message": "The new Customer E-Mail table field has no DataClassification property, leaving personal data unclassified.",
"location": {
"file": "src/Sales/CustomerValidation.Codeunit.al",
"file": "src/Sales/Customer.TableExt.al",
"line": 64,
"range": { "start-line": 60, "end-line": 64 }
},
"references": [
{ "path": "microsoft/knowledge/privacy/strsubstno-prebuild-breaks-error-telemetry-classification.md" }
{ "path": "microsoft/knowledge/privacy/data-classification-required-on-pii-fields.md" }
],
"confidence": "high"
}
@ -106,4 +106,3 @@ Output conforms to the DO output contract. A populated example:
"suppressed": []
}
```

View file

@ -89,7 +89,7 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/security/use-secrettext-for-credentials.md",
"id": "microsoft/knowledge/security/secrettext-for-credentials.md",
"severity": "blocker",
"message": "A bearer token is declared as a Text parameter and passed through the HTTP request path as plain text. The referenced guidance requires credentials to flow as SecretText end-to-end.",
"location": {
@ -98,20 +98,20 @@ Output conforms to the DO output contract. A populated example:
"range": { "start-line": 85, "end-line": 89 }
},
"references": [
{ "path": "microsoft/knowledge/security/use-secrettext-for-credentials.md" }
{ "path": "microsoft/knowledge/security/secrettext-for-credentials.md" }
],
"confidence": "high"
},
{
"id": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md",
"id": "community/knowledge/security/secrets-isolated-storage.md",
"severity": "minor",
"message": "An API key is assigned from a string literal rather than retrieved from IsolatedStorage or Key Vault at runtime.",
"message": "A setup table stores an API key in an ordinary Text field, exposing it through table reads and exports. Persist it in IsolatedStorage instead.",
"location": {
"file": "src/Integration/ApiClient.Codeunit.al",
"line": 201
"file": "src/Integration/ExternalServiceSetup.Table.al",
"line": 12
},
"references": [
{ "path": "microsoft/knowledge/security/never-hardcode-secrets-in-al.md" }
{ "path": "community/knowledge/security/secrets-isolated-storage.md" }
],
"confidence": "medium"
}
@ -134,4 +134,3 @@ The empty-corpus case — BCQuality's state until security knowledge files land
"suppressed": []
}
```

View file

@ -87,7 +87,7 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/style/apply-approved-label-suffixes.md",
"id": "microsoft/knowledge/style/label-suffix-approved-list.md",
"severity": "minor",
"message": "A Label named Text000 has no approved suffix (Msg/Err/Qst/Tok/Lbl/Txt). Per the referenced CodeCop AA0074 guidance, every Label and TextConst carries a suffix indicating its consuming call.",
"location": {
@ -95,7 +95,7 @@ Output conforms to the DO output contract. A populated example:
"line": 42
},
"references": [
{ "path": "microsoft/knowledge/style/apply-approved-label-suffixes.md" }
{ "path": "microsoft/knowledge/style/label-suffix-approved-list.md" }
],
"confidence": "high"
}
@ -103,4 +103,3 @@ Output conforms to the DO output contract. A populated example:
"suppressed": []
}
```

View file

@ -87,15 +87,15 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/ui/field-tooltips-start-with-specifies-and-end-with-period.md",
"id": "microsoft/knowledge/ui/show-caption-on-editable-fields.md",
"severity": "minor",
"message": "Field ToolTip is a fragment ('Customer name') — missing the 'Specifies' opener and the terminating period the house-style guidance requires.",
"message": "An editable page field sets ShowCaption = false, removing the visible and accessible label. Leave ShowCaption enabled or use a documented exception pattern.",
"location": {
"file": "src/Sales/CustomerCard.Page.al",
"line": 58
},
"references": [
{ "path": "microsoft/knowledge/ui/field-tooltips-start-with-specifies-and-end-with-period.md" }
{ "path": "microsoft/knowledge/ui/show-caption-on-editable-fields.md" }
],
"confidence": "high"
}
@ -103,4 +103,3 @@ Output conforms to the DO output contract. A populated example:
"suppressed": []
}
```

View file

@ -89,7 +89,7 @@ Output conforms to the DO output contract. A populated example:
},
"findings": [
{
"id": "microsoft/knowledge/upgrade/enum-changes-must-be-additive-at-the-end.md",
"id": "microsoft/knowledge/upgrade/enum-values-additive-at-end.md",
"severity": "blocker",
"message": "A new enum value was inserted at ordinal 1, shifting every subsequent value by one. Rows that store the old ordinal 1 will silently resolve to the new value. Per the referenced guidance, enum values must be appended at the end.",
"location": {
@ -97,7 +97,7 @@ Output conforms to the DO output contract. A populated example:
"line": 7
},
"references": [
{ "path": "microsoft/knowledge/upgrade/enum-changes-must-be-additive-at-the-end.md" }
{ "path": "microsoft/knowledge/upgrade/enum-values-additive-at-end.md" }
],
"confidence": "high"
}
@ -105,4 +105,3 @@ Output conforms to the DO output contract. A populated example:
"suppressed": []
}
```