Commit graph

201 commits

Author SHA1 Message Date
waldo
2439d5c412
knowledge(web-services): under schema 2.0 an API enum field is a contract by member name, under 1.0 by caption (#149)
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
What an API page publishes for an enum field depends on the OData schema
version: member names under 2.0, the caption as Edm.String under 1.0, never
the ordinal. Custom APIs defaulted to 1.0 through BC 23 and to 2.0 from BC 24.
LLMs assert one carrier as universal and get one direction wrong.

Co-authored-by: waldo1001 <12088142+waldo1001@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 16:26:24 +02:00
Kilian Seizinger
82422f94c9
Avoid Public Event publisher (#144)
* Avoid Public Event publisher

* knowledge(events): scope public-publisher detection to same-app raisers

The detection rule flagged every public event publisher, including ones
deliberately public so a sibling app can raise them - a contract `internal`
cannot express across app boundaries. Scope the finding to publishers that
are public although only their own app raises them, and record the
cross-app case as a valid Best Practice option.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0b67b90d-e4b4-4b92-9684-726c72c43b3f

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0b67b90d-e4b4-4b92-9684-726c72c43b3f
2026-09-02 16:07:18 +02:00
Stefano Demiliani
53e2cf2fa4
Add community guidance and review support for Business Central agents (#137)
* feat(community/agents): add AL agent quality guidance

- add 20 agent knowledge rules with good and bad AL samples
- clarify setup dialog shape, temporary persistence, permissions, profiles, instructions, capability registration, and interface wiring
- add the community-owned AL agents review skill
- make review fixture discovery layer-aware with custom, community, and Microsoft precedence
- document layer-aware evaluation behavior

* fix(community/agents): align setup and permission samples

- mark agent setup pages as non-extensible where required
- narrow the agent profile by hiding an unrelated sales-order field
- define a dedicated read-only permission set for the sales review agent
- assign AL-defined permission sets with system scope and the owning app ID
- clarify the permission scope guidance for default access controls

* Address agent review feedback
2026-09-02 16:06:25 +02:00
Kilian Seizinger
182180913e
ShowMandatory + OnQueryClosePage Check (#147)
* ShowMandatory + OnQueryClosePage Check

* Tighten mandatory-field review guidance

Require explicit ShowMandatory in the good sample, acknowledge that NotBlank marking is unreliable, and limit findings to visible editable controls on paths where users must supply a value.

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

Copilot-Session: 89dba8c8-6529-4b60-956f-875a59be499d

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Copilot-Session: 89dba8c8-6529-4b60-956f-875a59be499d
2026-09-02 15:21:06 +02:00
Kilian Seizinger
7a41d25bbd
Process Context via manual event subscriber pattern (#145)
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
* Process Context via manual event subscriber pattern

* improve knowledge article
2026-09-02 14:58:59 +02:00
António Silva
c39f723cae
Add community knowledge: AL boolean operators do not short-circuit (#136)
* Add community knowledge on AL boolean operators not short-circuiting

AL gives no short-circuit (lazy) evaluation guarantee for and/or/xor —
neither the AL operators nor the boolean operators documentation defines a
lazy evaluation order. LLMs trained on C#, JavaScript, or SQL assume the
left operand guards the right, which produces conditions where a guard
does not protect an unsafe subscript or a field read after a failed Get,
and where an expensive operand is paid on every path.

Adds community/knowledge/performance/boolean-operators-do-not-short-circuit.md
with good/bad AL companions. The guidance prefers nested if when one operand
depends on another, while keeping and/or legitimate for operands that are
independently safe and cheap, so a reviewer does not flag harmless bound
checks. This is the first article in a community performance domain; the
Microsoft performance review leaf skill already sources candidates by domain
across every enabled layer, so no skill change is needed to reach it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Add case true of pattern for long condition chains

Follow-up from PR review: nested if is the right answer for two or three
dependent conditions, but past that the nesting becomes the problem. AL's
case statement is the flat alternative — the control statements
documentation states a value set "must be an expression or a range" and
that the first matching value set executes, so case true of / case false of
accept boolean expressions and stop at the first match. That is the
laziness the boolean operators do not provide.

Adds case-true-of-for-long-condition-chains.md with good/bad AL companions:
case false of for guard chains where every condition must hold, case true of
for first-match dispatch. The bad sample shows both failure shapes — a
five-level if ladder, and the worse escape of collapsing it into an and
chain, which trades nesting for a real defect.

Cross-links both articles, and adds the threshold to the short-circuit
article's Best Practice so following it does not lead to a deep ladder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Comma-group the pure value sets in the case false of sample

Review feedback: the five value sets sharing exit(false) should be comma
separated. Applied to the three that are pure field reads with no order
dependency.

The Get and the Blocked read keep their own value sets. The documentation
guarantees that the first matching value set executes, which orders matching
across separate value sets; it says nothing about evaluation within one
comma-separated set, and the natural lowering of that is an equality-or
chain — where AL's or does not short-circuit. Grouping the Get with the
checks that must precede it would rest the sample's correctness on
undocumented behaviour, which is the defect these two articles exist to
prevent.

Encodes the boundary in the Best Practice section so the grouping is applied
where it is safe and not where it is not, and scopes the repeated-exit
detection signal explicitly to nested chains so the case sample does not read
as its own anti-pattern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Use a single exit(false) for the whole case false of chain

Review decision: all five conditions share one action, so they share one
comma-separated value set with a single exit(false).

Aligns the article's Best Practice with the sample — it previously told
authors to keep side-effecting conditions in their own value set, which the
sample no longer does — and drops the now-contradictory wording about listing
the failure action per condition.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Drop the parentheses from the case false of value sets

Applies NKarolak's review suggestion: a case value set needs no parentheses
around a comparison.

Encodes the rationale in the Best Practice section, since it is a real
advantage of the pattern and is not documented elsewhere in the repo. The AL
operator hierarchy places and/xor above the comparison operators and or just
above them too, so parentheses are mandatory in an and chain — A = B and
C = D misparses without them — while a case value set has no and to bind
tighter and needs none. That inverts the precedence most developers arrive
with from C#.

Also notes in the bad sample that its parentheses are not optional, so the
two samples contrast on parentheses as well as on evaluation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Address correctness review: or/xor pattern, case value-set ordering

Fixes two points from JesperSchulz's review on PR #136.

1. boolean-operators-do-not-short-circuit.md gave one fix — nested if — for
   and, or, and xor alike. That's only correct for and: nesting if A then if
   B then Action drops the A-true/B-false case of A or B, silently changing
   the result. Gives or its own early-exit pattern (if A then exit(true);
   exit(B)), warns explicitly against applying the and-rewrite to or, and
   clarifies that xor is not a short-circuit candidate in any language since
   its result always depends on both operands. Adds an or fixture
   (IsEligibleForFreeShipping) to both samples so an agent has a concrete
   pattern to match instead of extrapolating from the and-only examples.

2. case-true-of-for-long-condition-chains.md derived stop-at-first-match for
   one comma-separated value set from the documentation's guarantee about
   the first matching value set — plural, i.e. ordering across value sets,
   which is not the same claim. The good sample's Item.Get / Blocked pair
   depended on the one the docs don't make. Restructures the sample to only
   comma-group the three pure, order-independent checks; Get and Blocked
   keep their own value sets, in order, relying solely on the guarantee that
   is actually documented. Description and Anti Pattern now state that
   boundary so it isn't re-collapsed later.

Also carries forward a parenthesis fix (not Item.Blocked in the collapsed
bad sample) that was made two commits ago but never landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 14:48:33 +02:00
Jesper Schulz-Wedde
3e848d1ec2
knowledge(performance): align SetLoadFields placement with AL Guidelines (#130)
* knowledge(performance): align SetLoadFields placement with AL Guidelines (#120)

The AL Guidelines mark `SetLoadFields` placed before `SetRange`/`SetFilter`
as bad code and recommend filters first, while the BCQuality samples used
the opposite order — contradictory guidance across two Microsoft repos.

Per Learn (`Record.SetLoadFields`), "fields that are filtered upon are
always loaded", so the two orders produce an identical projection. The
upstream rule is a readability convention: keep `SetLoadFields` adjacent
to the read it governs.

- Reorder filters ahead of `SetLoadFields` in the six affected AL samples.
- State the placement convention in the Best Practice section.
- Record in Description that order does not change the projection, and
  that only a fieldless `SetLoadFields()` or a later overwriting call does.
- Add an Anti Pattern note so review agents treat the reverse order as a
  readability observation, never a performance defect.

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

* Clarify partial-record projection changes

Document AddLoadFields, SetBaseLoadFields, and Reset alongside SetLoadFields so the statement-order guidance does not imply those APIs leave the projection unchanged.

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

Copilot-Session: 89dba8c8-6529-4b60-956f-875a59be499d

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 89dba8c8-6529-4b60-956f-875a59be499d
2026-09-02 14:44:09 +02:00
wenjiefan
c213f1495e Exempt optional notification handlers from the HandlerFunctions execution rule
The narrowed UI-handler guidance still stated the execution rule without the
qualifier the linked Microsoft reference uses. The article said every listed
handler must execute at least once, and the testing leaf skill asked for
`[HandlerFunctions(...)]` to match the invoked handlers exactly. The reference
says every *nonoptional* listed handler must execute, and that send-notification
and recall-notification handlers can be optional. As written, an agent could
flag a deliberately unused optional notification handler.

The discriminator is narrower than the handler type. Both
`[SendNotificationHandler([HandlerIsOptional: Boolean])]` and
`[RecallNotificationHandler([HandlerIsOptional: Boolean])]` take an explicit
optionality argument, so `[SendNotificationHandler(true)]` is exempt while the
same attribute written without the argument stays nonoptional like every other
handler type. Keying the exemption on the argument rather than the type keeps it
checkable from the diff and avoids the opposite false positive, where an agent
stops flagging genuinely nonoptional notification handlers.

Changes:

- The article now states the nonoptional qualifier, explains that optionality is
  declared rather than inferred, and adds an explicit do-not-flag clause. That
  clause also forbids proposing removal, because the listed entry is what keeps
  the test passing on the runs where the notification does fire.
- The testing leaf skill carries the same boundary in its `ui-handlers-in-tests`
  cue, and its mechanical-fix list no longer allows removing a listed optional
  notification handler as a one-click suggestion.
- `SendNotificationHandler` and `RecallNotificationHandler` were missing from the
  skill's testing token list, so notification handlers were not reliably
  surfaced to the relevance step at all. Both are now listed.
- The good sample gains a test that lists an unreached
  `[SendNotificationHandler(true)]`; the bad sample gains the mirror image, an
  unreached `[SendNotificationHandler]` with no optionality argument. The pair
  differs only by that argument, which is the point.
- `evaluation/review-fixtures.json` pins the testing domain to
  `ui-handlers-in-tests` so the boundary is exercised: the good sample is the
  clean control at `minimumCleanRate` 1.0 and the bad sample is the expected
  finding. Keywords were retagged with `notification` and `optional-handler`.

validate_frontmatter.py reports 0 errors; Test-ReviewFixtures.ps1 passes with
32 cases across 16 leaf domains and resolves the testing fixture to this article.
2026-09-02 11:46:13 +02:00
Wenjie Fan
35a7e72f12
knowledge: three false-positive guards from BCApps PR 10277, 10278 and 10346 (#146)
data-modeling: add insert-only-transfer-may-rely-on-caller-cleanup. A filter-and-insert transfer routine was reported for stale rows and duplicate keys even though the field OnValidate trigger calls a sibling cleanup procedure that clears the same range immediately before it. Deciding this requires reading the caller, so the article asks reviewers to trace call sites and keeps uncleared or mismatched-filter paths reportable.

appsource: scope two-level-namespace-replaces-object-affix-not-extension-member-affix to apps that actually configure a mandatory affix. AS0011 only runs when AppSourceCop is enabled with a mandatory affix; a first-party in-box app that ships no such configuration is not subject to it. The member-affix requirement itself is unchanged for apps that do configure one.

testing: allow permission-tests-must-lower-the-execution-context to accept a composed role. The article demanded the exact permission set under test be assigned directly, so a test that lowered permissions through a role including that set and then asserted WritePermission was false was reported as a coverage gap. What matters is the effective context plus a boundary assertion, not which object the test names.

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-09-02 11:25:19 +02:00
Wael
f027e28f83
knowledge: improve review precision from BCApps PR 10080 feedback (#128)
* knowledge: improve review precision from BCApps PR 10080 feedback

* Update microsoft/knowledge/appsource/object-affixes-prevent-collisions.md

Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jesper Schulz-Wedde <JesperSchulz@users.noreply.github.com>
Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com>
2026-09-02 11:16:30 +02:00
wenjiefan
5016962b40 Align the IsHandled article slug, keywords and good sample with its narrowed scope
The article was rewritten to say a reset is required only when the value can
carry over, and its H1 was updated to match, but three artefacts still carried
the old "always initialize to false" premise:

- The slug still read `initialize-ishandled-to-false-before-publishing`, which
  contradicts the body. The slug is not cosmetic: Build-KnowledgeIndex.ps1
  ranks candidates on keywords, frontmatter dimensions, domain, path and title,
  so a stale path pushes selection back toward the behaviour this change
  narrows. Renamed to `reset-ishandled-only-when-the-value-can-carry-over`,
  following the existing precedent for conditional slugs such as
  `unreleased-symbol-change-is-not-a-breaking-change`.
- Keywords still listed `initialization` and `deterministic` and omitted
  `false-positive`, the tag this repository uses for suppression articles.
  Replaced with `carry-over` and `loop-iteration` and added `false-positive`.
- The good sample demonstrated only the "prefer separate fresh locals" clause
  and contained no reset at all, so the article's headline case had no positive
  example. It was also asymmetric with the bad sample, which gained a loop
  procedure showing a local that carries `true` into the next iteration.

Added the matching loop procedure to the good sample: a local declared outside
the loop is reset at the top of each iteration. That case cannot be solved by
introducing another local, because AL has no block scope, so it is the only
shape that demonstrates the reset the article still requires. It also gives the
engine the correct `suggested-code` shape for the loop finding; without it the
one-click fix adapted from the good sample would propose splitting the variable
rather than adding one line.

Also renamed the sample codeunits from "IsHandled Init ..." to
"IsHandled Carry Over ...", and updated the two references to the old slug:
the events leaf skill cue and the events pin in evaluation/review-fixtures.json.

validate_frontmatter.py reports 0 errors; Test-ReviewFixtures.ps1 passes with
32 cases across 16 leaf domains and resolves the events fixture to the renamed
article.
2026-09-02 11:08:16 +02:00
Wenjie Fan
00c9307483
knowledge(breaking-changes): adding a parameter to an event publisher is not a signature break (#139)
* knowledge(breaking-changes): exclude appended event parameters from the signature-change rule

The article's detection guidance flags 'a parameter added' on any shipped procedure. Applied to an event publisher that is bound to rather than called, this produced a false positive on BCApps PR 10278, where a trailing var parameter was appended to the existing IntegrationEvent OnAfterOpenForRecRef and the developer twice replied that adding a parameter to an existing integration event is not a breaking change.

It also contradicted events/add-new-event-parameters-at-the-end, which already states that existing subscribers still bind to the leading parameters. Scope the rule to called procedures, carve out appended event parameters as additive, and keep every other event signature edit - removal, reorder, retype, var flip - in scope. Point the IsHandled case at events/do-not-add-ishandled-to-an-existing-event, which owns that semantic concern.

* fix: event parameter additions are additive at any position, not only when appended

The first revision justified the carve-out with leading-prefix binding and limited it to parameters appended at the end. Verified against shipping BCApps code that AL binds subscriber parameters by name, not position, so an added parameter is additive wherever it is placed. Also corrects the cross-reference to events/adding-a-parameter-to-an-event-is-not-a-breaking-change, which already states this rule, and drops reordering from the list of edits that break binding.

* Route event signature edits to the analyzer-backed events article

Address review feedback: name AS0025, AS0063 and AS0077 for the var and rename cases instead of claiming them in the breaking-changes article, and point at events/treat-local-and-internal-events-as-subscriber-contracts which already owns them.

---------

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-09-02 09:24:54 +02:00
Wenjie Fan
85ceaaa1a4
knowledge(style): event subscribers bind by parameter name, so a shorter list is not a mismatch (#138)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* knowledge(style): allow event subscribers to omit trailing publisher parameters

The article told reviewers to copy the publisher signature exactly and reproduce every parameter verbatim. That contradicts events/add-new-event-parameters-at-the-end, which already states that existing subscribers bind to the leading parameters, and it produced a false positive on BCApps PR 10277 where a subscriber legitimately declared only the leading two of the publisher's three parameters.

Clarify that the name-match rule applies to every parameter the subscriber declares, state that AL binds on a leading prefix so trailing parameters may be omitted, and keep the real defect - a subscriber list that is not a prefix of the publisher's - as the anti pattern. Add the false-positive keyword for retrieval.

* fix: subscribers bind by parameter name, not by leading prefix

The first revision claimed AL binds a subscriber to a leading prefix of the publisher parameter list and that a parameter may not be skipped in the middle. That is wrong. Verified against shipping BCApps code: Test Runner - Mgt publishes OnBeforeTestMethodRun(var CurrentTestMethodLine; CodeunitID; CodeunitName; FunctionName; FunctionTestPermissions; var Skip), and ALTestRunnerResetEnvironment binds to it declaring (CodeunitID; CodeunitName; FunctionName; FunctionTestPermissions; var CurrentTestMethodLine) - omitting Skip and moving the first parameter to last. Binding is by name, so any subset in any order is valid. Detection now targets a parameter whose name or type matches nothing on the publisher.

---------

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-08-28 11:07:05 +02:00
Stefano Demiliani
293f9b13e7
knowledge(performance): add community rules for performance (#134)
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
* knowledge(performance): add community rules for JIT, locks, and false positives

These articles capture BC-specific mechanics agents still invert: partial-record JIT on writes, Reset clearing SetLoadFields, HttpClient inside write transactions, and batched number series, plus negative guidance that stops over-eager Query and IsEmpty "fixes".

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(community/performance): address PR #134 review comments

Fixes technical inaccuracies and behavioral issues raised during review
of the community performance knowledge articles.

avoid-currpage-update-in-onaftergetrecord.md
- Removed OnAfterGetCurrRecord from the Best Practice section. That
  trigger is itself implicitly re-entered on every refresh, so placing
  CurrPage.Update(false) inside it can re-trigger the very loop the rule
  warns about. Only OnAction remains as the recommended location.

batch-number-series-instead-of-getnextno-per-row.md
- Scoped the lock/contention claim to gapless (Normal) series only.
  Added explicit statement that Allow Gaps series use NumberSequence
  sequences and do not hold the series-line lock, so the anti-pattern
  detection signal now excludes Allow Gaps series.

countapprox-for-progress-not-count.bad.al / .good.al
- Changed FindSet(true) to FindSet() in both samples. The loop is
  read-only; UpdLock is not needed and was misleading.

countapprox-for-progress-not-count.md
- Qualified the Count() cost claim: it is expensive only when no SIFT
  key covers all filtered fields (forcing a SELECT COUNT(*)); a filtered
  count with matching SIFT coverage is cheap. Added a parenthetical
  noting that SIFT coverage cannot be assumed for arbitrary filters.

dataaccessintent-readonly-on-analytical-objects.md
- Changed bc-version from [all] to ["16.."]. DataAccessIntent was
  introduced at runtime 5.0 / BC 16 and has no effect in earlier
  versions.
- Added precision to the supported objects: pages must be PageType=API
  with Editable=false; for queries, replica routing only applies when
  the query is exposed via OData/API, not for AL-to-AL calls.

httpclient-inside-write-transaction-holds-locks.good.al
- Replaced the Commit()-before-HttpClient pattern with a two-codeunit
  task-deferral pattern. The write completes inside the caller's
  transaction (locks released naturally when it ends); a TaskScheduler
  task runs the HTTP call in a separate session where no write-
  transaction lock is held.

httpclient-inside-write-transaction-holds-locks.md
- Changed Best Practice to recommend TaskScheduler/job queue deferral
  as the primary remedy.
- Added an explicit warning against Commit() as a generic remedy: it
  irrevocably commits all prior writes in the current transaction, so a
  subsequent failure cannot roll them back. Commit() is appropriate only
  at top-level entry points where partial persistence is intentional.

oncompanyopen-subscribers-must-not-do-io.good.al
- Added a ClientType guard so the subscriber exits immediately in
  background task sessions (OnAfterLogin fires there too, which would
  create an unbounded task chain without the guard).
- Added a TaskScheduler.TaskExists idempotency check to avoid queuing
  duplicate tasks on repeated logins.
- Fixed the error-fallback codeunit in CreateTask from a self-reference
  to 0 (no error codeunit).
- Added a 60-second delay (CurrentDateTime() + 60000) so the task does
  not compete with the login session itself.

prefer-related-table-over-extension-on-hot-ledgers.md
- Changed bc-version from [all] to ["23.."]. The companion-table join
  optimisation (single join per base table, automatic exclusion on List/
  OData pages with partial records) was introduced in v23.
- Scoped the "join is always paid" claim: since v23 the join is
  excluded on List/ListPart/OData pages when no extension field is
  loaded under partial-record semantics, but it is still paid on every
  posting path and any AL code that accesses an extension field.

skip-setloadfields-on-write-and-transferfields.bad.al / .good.al / .md
- Changed the example scenario from Modify(false) (which is actually
  valid with a partial record) to TransferFields+Insert into a temporary
  record, which is a documented full-load operation.
- Removed Modify from the list of operations that force a full load.
- Added an explicit note in the .md that Modify itself is not in the
  full-load list; SetLoadFields is safe to use before Modify(false).

use-dedicated-lookup-pages-not-full-lists.bad.al
- Added a separate CardPart page definition (50101) to replace the
  self-referencing FactBox part that referenced the same list page it
  was embedded in. A part cannot refer to its own container page.

validate-on-partial-record-forces-jit.good.al
- Restored SetLoadFields to the good sample so it exercises a partial
  record and the contrast with .bad.al is field selection, not the
  absence of the feature. The good sample loads both Name and Search
  Name (the field Name.OnValidate writes), while the bad sample loads
  only Name, causing a JIT reload of Search Name on every Validate call.

* fix(community/performance): correct httpclient and oncompanyopen good samples

httpclient-inside-write-transaction-holds-locks.good.al
- Pass Customer.RecordId as the last argument to CreateTask so the task
  is bound to the single customer that was written, not to all customers.
- Declare TableNo = Customer on the task codeunit so the platform loads
  the bound record into Rec automatically when OnRun executes.
- Replace the FindSet loop over all customers with Rec."No.", preserving
  the one-customer scope of the original SyncCustomerLastName procedure.

oncompanyopen-subscribers-must-not-do-io.good.al
- Replace Session.GetCurrentClientType() with Session.CurrentClientType(),
  the correct platform method name.
- Fix the idempotency check: TaskScheduler.TaskExists() requires a Guid,
  not a codeunit integer ID. Store the Guid returned by CreateTask in
  IsolatedStorage (DataScope::Company) under a fixed key; on the next
  login read it back as Text, Evaluate it to Guid, and pass that Guid to
  TaskExists so the type matches the method signature.

* fix(community/performance): address review feedback

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-27 14:04:09 +02:00
Yahya Touil
9fab60153f
Add TransferFields SkipFieldsNotMatchingType guidance (#133)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* Add TransferFields SkipFieldsNotMatchingType guidance

* Update transferfields-skip-type-mismatch-can-drop-data.md

* Update transferfields-skip-type-mismatch-can-drop-data.good.al

* Move good sample reference under Best Practice

Aligns the article with the repo convention used by the sibling data-modeling files: the .good.al reference belongs under Best Practice and the .bad.al reference under Anti Pattern. Previously both pointers sat under Anti Pattern, leaving the good-sample reference orphaned in the wrong section.

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

Copilot-Session: 3c998c71-f30b-40f3-b714-87fafed505d8

---------

Co-authored-by: Jesper Schulz <jeschulz@microsoft.com>
Copilot-Session: 3c998c71-f30b-40f3-b714-87fafed505d8
2026-08-24 09:54:37 +02:00
dcenic
9203e3ce2b
Merge pull request #135 from microsoft/bugs/647560FixSetCurrentKeyHallucination
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
Correct severe misconception about SetCurrentKey in the knowledge base
2026-08-23 20:07:14 +02:00
Djordje Cenic
6e321d3c56 Correct severe misconception about SetCurrentKey in the knowledge base 2026-08-22 12:04:00 +02:00
wenjiefan
ead337f9cb Address review guidance feedback
Preserve independent event seams, cover loop-carried handled state, strengthen checkpoint and UI-handler fixtures, and align DeleteAll fallback guidance.

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

Copilot-Session: 10646e50-2d8b-4cca-b02b-dfa78629e6a1
2026-08-18 14:09:11 +02:00
wenjiefan
5f1cff2fb6 Refine self-improvement review guidance
Narrow IsHandled, label-scope, UI-handler, checkpoint, and bulk-operation guidance to evidence-backed false-positive boundaries.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-18 11:17:14 +02:00
Wenjie Fan
841b4e7cab
Merge pull request #131 from microsoft/gggdttt-fix-privacy-classification-guidance
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Correct table-level data classification guidance
2026-08-18 09:43:37 +02:00
wenjiefan
c1057d38b2 Scope tableextension requirement to Normal fields lacking a classification
The requirement to declare DataClassification explicitly in a tableextension
applies to the Normal fields it adds; FlowFields and FlowFilters are
SystemMetadata automatically and are covered by their own article. Being
added by a table extension is also not itself a finding - the finding is a
Normal field added by a table extension that has no valid explicit
DataClassification.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-17 15:25:14 +02:00
wenjiefan
f8acb6cbdd Scope DataClassification inheritance to fields declared in the table
Table-level DataClassification is the effective default only for Normal
fields declared inside that table object. A tableextension cannot set the
property (AL0246) and its added fields do not inherit the base table value,
so AS0016 still requires each of them to classify itself. State this in both
privacy articles so the guidance cannot suppress genuine findings on the
tableextension pattern, which is how most partner code adds fields.

Also narrow the inheritance claim to verified AppSourceCop behaviour rather
than asserting platform-level resolution, and make the sample's table-level
default semantically representative of its fields while keeping a legitimate
field-level override and demonstrating the tableextension boundary.

Verified with alc.exe 18.0.37.11445 + Microsoft.Dynamics.Nav.AppSourceCop.dll:
the revised sample produces no AS0016, and removing the explicit
classification from the tableextension field makes AS0016 fire.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-17 15:14:53 +02:00
wenjiefan
a668920e96 Correct table-level data classification guidance
Document that valid table-level classifications are inherited by fields and update the privacy fixture and related guidance accordingly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-17 13:16:12 +02:00
dependabot[bot]
455035432d
Bump the github-actions group with 3 updates (#127)
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
Bumps the github-actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/github-script](https://github.com/actions/github-script) and [actions/setup-python](https://github.com/actions/setup-python).


Updates `actions/checkout` from 4.4.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](11d5960a32...3d3c42e5aa)

Updates `actions/github-script` from 7.1.0 to 9.0.0
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](f28e40c7f3...3a2844b7e9)

Updates `actions/setup-python` from 5.6.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](a26af69be9...5fda3b95a4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/github-script
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-17 12:51:59 +02:00
Dan Fiedler
91f52f8b4f
Pin GitHub Actions to full-length commit SHAs (#126)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
2026-08-14 10:24:42 +02:00
Stefan Maroń
a58b23d0f9
knowledge(data-modeling): TableRelation delete/rename asymmetry and the xRec before-image contract (#125)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Three related concerns, each proven by executable tests rather than recall.
They were extracted from a real defect that shipped through a six-reviewer
panel undetected, which is the admission test passing on behavior rather than
on theory.

owning-table-must-delete-dependents-in-ondelete
  AL has no cascading delete. What makes it missable is an asymmetry: the
  platform DOES keep references correct on rename via TableRelation, so a
  developer who learns that and generalizes it to delete ships orphans. Also
  notes the permission trap (delete rights needed on the dependent table, not
  just the parent).

validate-table-relation-false-suppresses-rename-propagation
  The non-obvious half. The property name implies input validation only, but
  disabling it also switches off rename propagation. Verified against a parent
  renamed once while a child held three fields: a normal relation (follows),
  the same relation with validation disabled (does NOT follow), and a field
  with no relation at all (does not follow) — the third being the control that
  proves the test can detect a non-propagating field.

xrec-is-a-before-image-only-in-some-triggers
  Corrects both the naive belief that xRec is always the previous record and
  the folk rule that it 'only works from a page'. The behavior is per-trigger:
  a genuine before-image in OnRename and OnDelete regardless of driver, a
  mirror of Rec in OnInsert/OnModify when driven from code, and a real
  before-image in those two only when a page drove the write. That last
  asymmetry is why an OnModify comparison against xRec passes manual page
  testing and silently no-ops in a job queue.

Targets /community per CONTRIBUTING — general BC knowledge, not fork-specific.
Frontmatter validator clean; Test-ReviewFixtures passes (32 cases, 16 leaves).
2026-08-10 13:11:38 +02:00
Wenjie Fan
1687b57c99
Merge pull request #124 from microsoft/bcq/642303-fp-guards
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Add FP guards: field relocation to tableextension + event parameter addition (bug 642303)
2026-08-04 13:00:44 +02:00
wenjiefan
6d1fada5a4 Add FP guards for field relocation to tableextension and event parameter addition
Two knowledge false-positive guards addressing bug 642303 (agent FPs on BCApps PR #9607):

- breaking-changes: relocating a field to a tableextension in the same app under the same field ID/name is a relocation, not a deletion/rename; the field still resolves on the table, so it must not be flagged as a deleted shipped field or require ObsoleteState staging. Scoped to the contract axis; silent on data migration.

- events: adding a parameter to an event publisher does not break existing subscribers (subscribers bind by name and match a subset), so the addition itself must not be reported as a breaking signature change.
2026-08-04 10:41:03 +02:00
Wenjie Fan
31d110abc8
Merge pull request #123 from microsoft/fix/bridge-skill-manifest-path
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Fix bridge skill manifest references after #122 root move
2026-07-30 11:35:00 +02:00
wenjiefan
88dcfd1a76 Fix bridge skill manifest references after #122 root move
#122 moved the plugin manifest to the root plugin.json (and moved the
bridge skill to skills/bcquality-al-review/), but the bridge SKILL.md
prose still pointed at the now-deleted .claude-plugin/plugin.json:

- ## Plugin root told the host to resolve PLUGIN_ROOT by anchoring on
  .claude-plugin/plugin.json, a marker that no longer exists, so the
  location-based fallback could never find it. Anchor on root plugin.json.
- ## Notes described .claude-plugin/plugin.json as the manifest the plugin
  uses and root plugin.json as a future form -- the reverse of reality
  after #122. Describe root plugin.json as canonical and .claude-plugin/
  marketplace.json as the marketplace entry.

Doc-only; no behavior change.
2026-07-30 11:13:33 +02:00
Wenjie Fan
78389629a6
Merge pull request #122 from microsoft/fix/plugin-manifest-format
Move plugin.json to plugin root; declare skills for CLI/marketplace compliance
2026-07-30 09:45:07 +02:00
wenjiefan
5970984603 Move plugin.json to plugin root; declare skills for CLI/marketplace compliance
The GitHub Copilot CLI plugin reference requires plugin.json at the root of the plugin directory. BCQuality shipped it only under .claude-plugin/, which is tolerated by --plugin-dir but is non-canonical and can be rejected on the marketplace / 'plugin install owner/repo' path.

Mirror the proven microsoft/BC-ALAgents al-review plugin layout: move plugin.json to the repo (plugin) root and add an explicit skills array plus repository/license/keywords metadata to both plugin.json and marketplace.json. The skills array pins the one real skill (skills/bcquality-al-review/), avoiding ambiguity with the loose meta .md files in skills/.

Verified: 'copilot --plugin-dir <clone>' still loads the bcquality plugin and the bcquality-al-review skill registers at runtime, identical to before.
2026-07-29 15:58:02 +02:00
Wenjie Fan
ad8ccde595
Merge pull request #119 from microsoft/bcq/batch2-fp-guards
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Add batch-2 FP guards: sentence-case action captions + PK Get is transaction-cached
2026-07-22 09:40:01 +02:00
wenjiefan
2b401aa38e Add batch-2 FP guards: sentence-case action captions + primary-key Get is transaction-cached 2026-07-21 11:08:04 +02:00
Wenjie Fan
8fb7f61808
Merge pull request #118 from microsoft/bcq/batch1-fp-guards
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
knowledge: 3 FP-suppression guards from BC apps negative feedback
2026-07-21 10:56:16 +02:00
wenjiefan
c618071ea6 knowledge: add 3 FP-suppression guards from BC apps negative feedback
- upgrade/obsoletereason-need-not-restate-removal-version: ObsoleteTag carries the version; do not flag ObsoleteReason for omitting it (PR 8290)

- error-handling/unchecked-get-throws-when-record-not-found: a bare Rec.Get() errors on missing record; it is not silently ignored (PR 8584)

- performance/onaftergetcurrrecord-is-not-per-row: OnAfterGetCurrRecord fires on selection change, not per row; CalcFields there is not N+1 (PR 8617)
2026-07-21 09:45:09 +02:00
Wenjie Fan
82f6cd4e40
Merge pull request #117 from microsoft/fix/tooltip-agent-safety-net
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
tooltip: PR review flags genuinely-missing tooltips instead of deferring to AA0218
2026-07-20 14:36:58 +02:00
wenjiefan
89bf8fde31 tooltip: PR review flags genuinely-missing tooltips instead of deferring to AA0218
The v1.4 policy deferred every missing-tooltip case to compiler analyzer AA0218. But AA0218 severity is per-app ruleset config and is routinely downgraded to info/None or disabled, so a genuine gap can ship unflagged. PR review is the last line of defence and should raise it independently.

Keeps the false-positive guard intact: a bound field whose source table field supplies a ToolTip still inherits it and is NOT flagged. Adds the genuinely-missing case (bound field whose source is also tooltip-less, or an unbound control) as a medium-severity finding. Updates both the ui inheritance article and the style AA0218 article.
2026-07-20 14:30:29 +02:00
Wenjie Fan
712dee9ec1
style-review: calibrate variable-declaration order (AA0021) to info (#109)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Online eval shows style/variable-declaration-order-by-type firing as false positives (tp/fp 2/1) at minor. The article title itself is 'Order variable declarations by type (CodeCop AA0021)', so it is analyzer-redundant exactly like the this-keyword AA0248, label-suffix AA0074, and ToolTip rules already calibrated to info. Add AA0021 to the analyzer-redundant list so it emits at info and stops competing with substantive style review.

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-07-17 14:17:32 +02:00
Wenjie Fan
1bf5a3b276
Add precision guards for systematic agent false-positive patterns (#112)
* Add precision guards for systematic agent false-positive patterns

Encodes reviewer-confirmed FP guards from the online eval: tooltip-inherited, page-trigger default return, drill-down filter not visible in diff, dual-trigger CalcFields (do.md); and a released-baseline precondition for breaking-change/upgrade findings on never-shipped symbols.

* Scope suggested-code and location to exactly the changed lines

Addresses reviewer-reported misplaced suggestions from the eval: insert-only-property emitting the whole field, single-statement rewrites anchored on the procedure name, and reductive multi-line collapses. The skill now emits a location range that matches precisely the rewritten lines.

* Correct suggested-code scoping guidance to match one-click anchor mechanics

A lone inserted line matches no existing file line and cannot be anchored; bracket the new line with one adjacent unchanged line instead. Reductive collapses omit suggested-code and fall back to a manual snippet.

* Move BC-specific FP guards out of do.md into leaf skills

do.md is the stable action-skill template and must stay domain-agnostic (JesperSchulz review). Relocate the four known false-positive patterns to their domain leaves: ToolTip-inheritance to al-ui-review; drill-down/lookup filtering and CalcFields lifecycle to al-performance-review; page-trigger exit(true) semantics to al-error-handling-review.

* Move suggested-code line-scoping guidance out of do.md into al-code-review

do.md must not carry instructions for how the review skill behaves (JesperSchulz review). Relocate the location/suggested-code precise-span rules to al-code-review's existing Suggested-code guidance section. do.md is now unchanged vs main.

* Move false-positive guards from skills into knowledge files

Keep review skills slim (finders/appliers). The FP guards and released-baseline preconditions previously embedded in leaf skills become negative-clarification knowledge articles in their domains, and the agent-findings policy edits to al-ui/al-privacy are reverted to main. Adds 6 knowledge files: error-handling (page-boolean-triggers-default-to-true), ui (bound-page-field-inherits-source-field-tooltip), performance (calcfields-in-both-getrecord-triggers-is-not-redundant, page-effective-filter-may-live-outside-the-diff), breaking-changes (unreleased-symbol-change-is-not-a-breaking-change), upgrade (unreleased-schema-change-needs-no-upgrade-path).

* Revert branch's suggested-code scoping addition in al-code-review

The three location-span shapes added to al-code-review are output-format mechanics, not domain knowledge: one-click span correctness is the engine's job (Resolve-SuggestionPlacement) and do.md already owns the suggested-code/location contract. The AL concerns the examples illustrate are already covered by existing knowledge (use-isempty-for-existence-check, data-classification-required-on-pii-fields, no-space-before-method-parenthesis). Restores al-code-review to main; the branch now adds only the 6 knowledge files.

* Restore al-ui/al-privacy review skills to base (zero diff in PR)

These two leaf skills carried an accidental net change against the PR merge-base because an earlier revert used the current origin/main (post-#110) instead of the branch base (pre-#110). Restoring them to the merge-base version removes them from the PR diff entirely. Three-way merge still preserves main's #110 suppression.

---------

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-07-17 14:17:04 +02:00
Jesper Schulz-Wedde
b9c57ba6f9
Document the skill-vs-knowledge boundary so BC facts land in knowledge files (#114)
Reviewing #112 surfaced that the authoring docs never state where a new BC
fact (or a false-positive guard) belongs, so an agent iterated do.md -> leaf
skills -> knowledge files across two review rounds before landing knowledge
in a knowledge article. The information to decide existed but was split across
README/do.md/write.md and framed only as positive best practices.

- do.md: add "Skills hold mechanics; knowledge files hold BC facts" — a skill
  is a finder/applier; every BC behavioural claim it acts on must be a cited
  knowledge file. Names negative knowledge (false-positive guards) as first
  class, and forbids both adding a BC fact to a skill and restating an
  article's fact inline (the drift/duplication smell).
- write.md: add "Is this a knowledge file?" decision gate at the top, plus a
  "Negative knowledge is first-class" section with the Description/Best
  Practice/Anti Pattern mapping and a worked example.
- README: note that false-positive-preventing files are first-class knowledge
  and add a reviewer heuristic to Contributing.

Prose-only additions; validator passes. Meta-skill contract semantics are
unchanged, so version stays 1 (maintainers may bump if they consider the
explicit boundary rule a contract change).


Copilot-Session: 76eba53e-18cd-4618-a205-3607f260f9f4

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-17 12:15:22 +02:00
Wenjie Fan
29555c3796
Merge pull request #110 from microsoft/fix/suppress-lowyield-agent-findings
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
review: stop reference-less agent findings in privacy and UI/accessibility leaves
2026-07-16 23:32:50 +02:00
wenjiefan
cdd3d99cf8 review: stop emitting reference-less agent findings in privacy and UI/accessibility leaves
Online eval (182 PRs) shows the reference-less agent-finding channel is where 86% of false positives come from, and it is net-negative in the lowest-yield domains: privacy agent findings score 0 TP / 8 FP and UI/accessibility 1 TP / 11 FP. Restrict these two leaves to knowledge-backed findings only; an uncovered concern is omitted (and, if material and recurring, fixed durably by adding a BCQuality article per the self-improvement loop) instead of emitted with references: [].
2026-07-15 14:57:17 +02:00
Jesper Schulz-Wedde
186d8a1314
Complete AL review knowledge readiness (#108)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* Complete AL review knowledge readiness

Fill telemetry and Query coverage, strengthen thin review domains, correct audited content defects, and add deterministic cheap-model evaluation and reference-integrity safeguards.

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

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Generalize review fixture discovery

Derive smoke cases from the leaf, domain, and paired-sample conventions so new leaves require no scoring-contract changes. Keep only exceptional selection/context overrides and fail when retrieval metadata cannot rank the selected article.

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

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Preserve published field IDs in sample

Keep the existing Email and Contact Email field IDs unchanged, clarify that the sample represents an independent baseline, and use a local breaking-change rule for the generic smoke evaluation.

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

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Clarify published field identity rules

State explicitly that a published field keeps its ID, name, and type while a replacement is added as a separate field under an unused ID.

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

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Align field obsoletion sample baselines

Use Email field ID 3 as the shared baseline so the bad example demonstrates a same-ID rename while the good example retains the original field and adds a separate replacement.

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

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-15 10:55:25 +02:00
Jesper Schulz-Wedde
ae04938c03
Emit human-readable domain label on review findings (#54)
* Emit human-readable domain label on review findings

Add an optional findings[].domain field to the DO review output contract so
each finding carries its own human-readable review-domain display label. Leaf
review skills set it on every finding they emit; the al-code-review super-skill
copies it verbatim during rollup and sets it to "Agent" for its own
cross-cutting agent findings. This decouples consumers from BCQuality's domain
taxonomy: they render finding.domain verbatim instead of maintaining a
sub-skill-id -> label map.

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

* Define domain display-label constraints

Clarify that review domains may contain internal whitespace, punctuation, case-sensitive text, and non-ASCII characters. Require consumers to preserve and safely encode the complete label instead of relying on lossy slugs, matching the replacement BC-ALAgents consumer.

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

Copilot-Session: 77d0a40e-8bf5-40ac-a450-40eb0255db03

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-15 10:44:50 +02:00
Wenjie Fan
809af9708e
Privacy DataClassification fixes + keep Label-scope findings at minor (#102)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* Fix DataClassification default fact and broaden classification taxonomy

* Keep Label-scope findings at minor; no analyzer enforces label scope

---------

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-07-14 14:23:03 +02:00
Jesper Schulz-Wedde
3d29c172a9
Promote validated community knowledge (#105)
Move eight net-new rules into the Microsoft layer, remove six overlapping articles, and update review skill discovery and references.

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

Copilot-Session: 0b130227-d418-4bc0-9e7d-ec6a37adf039

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-14 14:20:27 +02:00
Wenjie Fan
be1b92b624
style-review: fix example finding id to match references[0].path (#101)
The al-style-review worked example set findings[0].id to a non-existent
knowledge file (apply-approved-label-suffixes.md) while references[0].path
points to the real file (label-suffix-approved-list.md). The DO output
contract requires id to equal references[0].path for citation-based
findings. Align id to the existing file.

Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
2026-07-14 12:59:25 +02:00
Jesper Schulz-Wedde
0bb1065bc3
Add P0 integration and control add-in runtime guidance (#100)
* Add P0 integration and control add-in guidance

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

Copilot-Session: 02baffe8-0600-430d-81fa-a9993685e7cb

* Correct API part multiplicity guidance

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

Copilot-Session: 02baffe8-0600-430d-81fa-a9993685e7cb

* Refine API part multiplicity guidance

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

Copilot-Session: 1c37924e-9749-4e63-9d58-bd73d659f736

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-14 12:53:26 +02:00
Jesper Schulz-Wedde
e0ebdd35c7
Add lifecycle error and privacy knowledge (#99)
* Add lifecycle error and privacy knowledge

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

Copilot-Session: 95c06ad8-377d-4faa-8d07-06300b1c81ec

* Fix lifecycle privacy review findings

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a26cd6d6-ff49-433e-bc53-f645c455ebdd

* Refine lifecycle privacy retrieval

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

Copilot-Session: 95c06ad8-377d-4faa-8d07-06300b1c81ec

* Make review gates explicit

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

Copilot-Session: 95c06ad8-377d-4faa-8d07-06300b1c81ec

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-14 12:52:56 +02:00