Skip to content

Ruleset hardening: promote 5 rules from Warning to Error - #10251

Open
Jesper Schulz-Wedde (JesperSchulz) wants to merge 9 commits into
mainfrom
jesperschulz-ruleset-hardening-4
Open

Ruleset hardening: promote 5 rules from Warning to Error#10251
Jesper Schulz-Wedde (JesperSchulz) wants to merge 9 commits into
mainfrom
jesperschulz-ruleset-hardening-4

Conversation

@JesperSchulz

@JesperSchulz Jesper Schulz-Wedde (JesperSchulz) commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Continues the ruleset hardening work from #10088 and #10209. Promotes 5 rules back to Error by removing their overrides from src/rulesets/base.ruleset.json, and resolves every violation those rules report.

Override count: 100 → 95.

Promoted: AL0547, AL0679, AW0014, AS0058, PTE0007.

Fixed in code

Rule Fix
AL0679 The Email Logging Install codeunit was missing from the Email Logging - Obj. permission set, so it was not covered by any entitlement. Every other object in the app was already listed.
AW0014 The hidden F&unctions group on the ES Account Schedule Names page contained Export Schedules to ASC format, which is the target of a promoted actionref. Hiding the group made the promoted action unreachable, so the Visible = false is removed.

Accepted with #pragma warning disable

Each suppression is documented in place with the reason.

Rule Sites Why it is accepted
AL0547 4 Published integration events declaring GlobalVarAccess. Turning it off would break existing external subscribers.
AS0058 / PTE0007 26 asserterror statements in 11 test library codeunits. These are Subtype = Normal helpers that deliberately wrap asserterror on behalf of test codeunits, which is exactly what these rules flag.

Deferred

These were in the original scope but need real remediation, a dedicated PR, or domain-owner input, so their overrides are retained:

  • AS0052needs its own PR. 61 app.json manifests have a missing or empty url, 44 of them under src/Layers/W1, each requiring propagation into the localized layers. CI only ever revealed two sites at a time because the build halts at the first project that errors, so the true scope was not visible up front.
  • AL0523cannot be suppressed. The Posted Deposit Line duplicate-method diagnostic is emitted without a source location (it is a project-level comparison against the Base Application symbol package), so #pragma warning disable has nothing to attach to. Resolving it means renaming released public methods.
  • AL0717 — FlowFields with no CalcFormula (Script Editor Line."Has Errors", Statutory Report Data Header."Requisites Quantity" / ."Set Requisites Quantity"). These are actively CalcFields'd, so they silently always return 0/false. Genuine latent bugs; suppressing them would enshrine the bug.
  • AL0589 — duplicate report column/data item names across ~27 reports. Renaming columns breaks RDLC and Word layouts.
  • AL0520 — references to removed tables (Intrastat, Invoice Post. Buffer, Payment Buffer, VAT Code). Real obsolescence debt.
  • AL0749 — public method parameters with Internal types. Resolving means changing accessibility, i.e. an API change.
  • AL0719, AW0003, AW0004 — small counts but the sites could not be pinpointed from CI logs alone (CI reports no file/line).

Notes

Related to AB#640773

Jesper Schulz-Wedde and others added 4 commits August 12, 2026 11:20
AD0001 and AL0640 are overridden to Error in base.ruleset.json, which is
already the effective severity: base.ruleset.json sets generalAction to
Error, and neither rule is downgraded by the included ruleset.json.

Removing the two entries is therefore a no-op for analysis behaviour and
simply reduces the override list from 105 to 103.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
AA0471, AA0472 and AA0474 have no violations anywhere in the repository, so
their overrides are removed outright.

AA0473 and AS0112 each have a handful of violations. Rather than keeping the
rules disabled for the whole repository, the individual sites are marked with
#pragma warning disable so they become accepted violations, and the overrides
are removed as well.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
CI showed that the earlier scope was based on incomplete local coverage:
AA0473 and AS0112 have several hundred violations across the repository, so
their overrides are restored and they are left for dedicated remediation.

AA0471 and AA0474 turned out to have only six sites in total, all in the
Withholding Tax app, and all of them are genuine omissions rather than
acceptable exceptions. They are fixed by supplying the missing
AutoFormatExpression, matching what neighbouring fields in the same tables
already do. The accumulator table has no currency, so it formats in local
currency.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
Removes 14 overrides from src/rulesets/base.ruleset.json so the rules
inherit Error from ./ruleset.json. Selected from CI-derived violation
counts (all estimated at 10 or fewer distinct sites):

  AW0003, AW0004, AW0014, AL0520, AL0523, AL0547, AL0589, AL0679,
  AL0717, AL0719, AL0749, AS0052, AS0058, PTE0007

Override count: 100 -> 86. CodeCop (AA*) rules are deliberately excluded
here because removing CodeCop entries perturbs AA0021 reporting.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
@github-actions github-actions Bot added AL: Apps (W1) Add-on apps for W1 Finance GitHub request for Finance area labels Aug 14, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 14, 2026
Reduces the promotion set from 14 rules to the 7 whose violations are
fully resolved here. Override count: 100 -> 93.

Fixed in code:
  AL0679  Email Logging Install codeunit was missing from the
          'Email Logging - Obj.' permission set.
  AW0014  The hidden 'F&unctions' group on the ES Account Schedule Names
          page contained the target of a promoted actionref, which made
          the promoted action unreachable.
  AS0052  Two app.json 'help' URLs had a leading space.

Accepted with #pragma warning disable (documented in place):
  AL0547  Four published integration events declare GlobalVarAccess.
          Turning it off is a breaking change for existing subscribers.
  AL0523  Three 'Posted Deposit Line' methods are part of the released
          public surface; renaming them would be breaking.
  AS0058 / PTE0007
          26 asserterror statements in 11 test library codeunits that
          intentionally wrap asserterror for use by test codeunits.

Deferred (overrides retained, need real remediation or owner input):
  AL0520 obsolete table references, AL0589 duplicate report column names
  (breaks RDLC layouts), AL0717 FlowFields with no CalcFormula (broken
  fields, needs domain input), AL0719, AL0749 internal types on public
  methods, AW0003, AW0004 Blob page fields.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
@JesperSchulz Jesper Schulz-Wedde (JesperSchulz) changed the title Promote 14 low-violation rules back to Error in base ruleset Promote 7 rules back to Error and resolve their violations Aug 14, 2026
…cationTestLibrary manifests

AL0523 is reported without a source location (project-level symbol
comparison), so #pragma warning disable cannot suppress it. Restore its
Warning override and revert the pragma in PostedDepositLine.Table.al.

AS0052 fired on the DemoTool and Application Test Library views because
their layer manifests do not declare 'url'. Add the standard Microsoft
link used by the other 786 app.json files in the repository.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
@JesperSchulz Jesper Schulz-Wedde (JesperSchulz) changed the title Promote 7 rules back to Error and resolve their violations Ruleset hardening: promote 6 rules from Warning to Error Aug 14, 2026
The Verify App Changes propagation check requires that a change to a W1
layer manifest is mirrored into the localized layers that override it.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
@JesperSchulz
Jesper Schulz-Wedde (JesperSchulz) marked this pull request as ready for review August 17, 2026 08:01
@github-actions github-actions Bot added Other GitHub request for other area than SCM, Finance or Integration Ownership: Needs Review Ownership is Other, low confidence, or needs manual correction and removed Finance GitHub request for Finance area labels Aug 17, 2026
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": " https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview",
"help": "https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ AppSource}$

The corrected help URL (https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview) is still more than two path levels deep. Per AppSource Copilot grounding guidance, Copilot truncates such URLs to the first two path segments (.../dynamics365), silently grounding on unrelated sibling content instead of this app's documentation.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.33.4

"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": " https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview",
"help": "https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ AppSource}$

The corrected help URL (https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview) is still more than two path levels deep. Per AppSource Copilot grounding guidance, Copilot truncates such URLs to the first two path segments (.../dynamics365), silently grounding on unrelated sibling content instead of this app's documentation.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.33.4

@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟠\ High\ Severity\ —\ Privacy}$

The touched Normal fields "Accumulated Base Amount" and "Accumulated WHT Amount" rely on the table's DataClassification and do not declare field-level DataClassification. Per AppSourceCop AS0016, a table-level DataClassification does not cascade to Normal fields, so these fields remain non-compliant with the field-level classification requirement even after this PR touches them.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        field(8; "Accumulated Base Amount"; Decimal)
        {
            Caption = 'Accumulated Base Amount';
            AutoFormatType = 1;
            // The accumulator only ever holds local currency amounts.
            AutoFormatExpression = '';
            DataClassification = CustomerContent;
            ToolTip = 'Specifies the accumulated base amount for the withholding tax threshold accumulator.';
        }
        field(9; "Accumulated WHT Amount"; Decimal)
        {
            Caption = 'Accumulated Withholding Tax Amount';
            AutoFormatType = 1;
            // The accumulator only ever holds local currency amounts.
            AutoFormatExpression = '';
            DataClassification = CustomerContent;
            ToolTip = 'Specifies the accumulated withholding tax amount for the withholding tax threshold accumulator.';
        }

Knowledge:

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.33.4

@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟠\ High\ Severity\ —\ Privacy}$

The touched Normal field "Taxable Base Amount" does not declare field-level DataClassification, even though other fields in this same table (e.g. lines 95 and 272) already do. This leaves the field non-compliant with AppSourceCop AS0016 and inconsistent with the table's own established pattern.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        field(112; "Taxable Base Amount"; Decimal)
        {
            Caption = 'Taxable Base Amount';
            AutoFormatType = 1;
            AutoFormatExpression = Rec."Currency Code";
            Editable = false;
            DataClassification = CustomerContent;
        }

Knowledge:

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.33.4

The build halts at the first project that reports an error, so CI only
ever surfaced two AS0052 sites at a time. Enumerating the repository
shows 61 app.json manifests with a missing or empty 'url', 44 of them
under src/Layers/W1 and each requiring propagation to the localized
layers. That is far too large to carry here, so AS0052 keeps its Warning
override and the manifest changes are reverted.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
@JesperSchulz Jesper Schulz-Wedde (JesperSchulz) changed the title Ruleset hardening: promote 6 rules from Warning to Error Ruleset hardening: promote 5 rules from Warning to Error Aug 17, 2026
{
Caption = 'Accumulated Base Amount';
AutoFormatType = 1;
// The accumulator only ever holds local currency amounts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Data\ Modeling}$

The new LCY-only AutoFormatExpression ('') on "WHT Threshold Accumulator" fields "Accumulated Base Amount" and "Accumulated WHT Amount" hard-codes these totals as local-currency values, but the accumulator is populated from "Withholding Tax Entry"."Taxable Base Amount", and that source table itself stores a "Currency Code" and uses Rec."Currency Code" for its own AutoFormatExpression in this same PR. This makes the added comment's LCY-only claim architecturally inconsistent with the actual data flow, and risks mislabeling accumulated foreign-currency amounts as local currency in the UI. Either confirm/enforce that only LCY amounts ever flow into the accumulator (e.g. via validation or a comment referencing where that invariant is enforced), or source the AutoFormatExpression from a persisted currency-code field consistent with the source entries.

Agent judgement — not directly backed by a BCQuality knowledge article.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.33.4

SnapTestRunner and TestRunner are Subtype = TestRunner, not Subtype =
Test, so both rules fire on their asserterror statements. They use
asserterror deliberately: to probe whether a lock file could be acquired,
and to surface permission errors as a test failure.

A repository-wide scan confirms these were the last three uncovered
sites; all 13 files that use asserterror outside a Subtype = Test
codeunit are now pragma-covered.

Related to AB#640773

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e6fd312-fe92-4215-8333-f98ba0a2e25d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: Apps (W1) Add-on apps for W1 Other GitHub request for other area than SCM, Finance or Integration Ownership: Needs Review Ownership is Other, low confidence, or needs manual correction

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant