Correct event compatibility guidance

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 645349fd-1892-48f3-8a84-db77d6abd1c3
This commit is contained in:
Jesper Schulz-Wedde 2026-07-14 12:11:38 +02:00
parent 23af51e02d
commit 6c5133fe7e
9 changed files with 54 additions and 47 deletions

View file

@ -1,7 +1,7 @@
---
bc-version: [all]
domain: events
keywords: [local-event, internal-event, event-subscriber, compatibility, access-modifier, integration-event, business-event, appsourcecop, as0025]
keywords: [local-event, internal-event, event-subscriber, compatibility, access-modifier, integration-event, business-event, parameter-name, var-parameter, appsourcecop]
technologies: [al]
countries: [w1]
application-area: [all]
@ -11,16 +11,16 @@ application-area: [all]
## Description
The `local` and `internal` access modifiers on Business and Integration event publishers restrict who can raise the procedure; they do not prevent dependent extensions from subscribing. Once shipped, the event name and existing parameter names, types, order, and passing modes are compatibility contracts even when the publisher is not public. This differs from `[InternalEvent]`, which is module-only except for modules named by `internalsVisibleTo`.
The `local` and `internal` access modifiers on Business and Integration event publishers restrict who can raise the procedure; they do not prevent dependent extensions from subscribing. Once shipped, the event name and each existing parameter's name, type/subtype, and value-versus-`var` passing mode are compatibility contracts even when the publisher is not public. Parameter order is not a subscriber contract because subscribers bind the parameters they use by name. This differs from `[InternalEvent]`, which is module-only except for modules named by `internalsVisibleTo`.
## Best Practice
Preserve a shipped Business or Integration event's identity and existing parameters regardless of its procedure access modifier. A compatible trailing parameter may be added to a `local` or `internal` event as described by `add-new-event-parameters-at-the-end`; for an incompatible signature or a public publisher, add a new event and keep the original.
Preserve a shipped Business or Integration event's identity and every existing parameter's name, type/subtype, and passing mode regardless of the procedure access modifier. AS0025 protects names and types, while AS0063 and AS0077 protect removal and addition of `var`. New parameters may be added at any position on a `local` or `internal` event because subscribers can omit them; public event procedures follow the stricter caller contract described by `add-new-event-parameters-at-the-end`.
See sample: `treat-local-and-internal-events-as-subscriber-contracts.good.al`.
## Anti Pattern
Renaming, removing, reordering, or changing an existing parameter because the event publisher procedure is `local` or `internal`. AppSourceCop AS0025 checks these subscriber-breaking changes because dependent event subscribers can still bind to the event.
Renaming or removing an existing parameter, changing its type/subtype, or adding/removing its `var` modifier because the event publisher procedure is `local` or `internal`. AppSourceCop checks these subscriber-breaking changes because dependent event subscribers can still bind to the event. Reordering unchanged parameters, or inserting a new parameter among them, is not this anti-pattern.
See sample: `treat-local-and-internal-events-as-subscriber-contracts.bad.al`.