Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/claude-evaluation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ on:
- "bug-fix"
- "test-generation"
- "code-review"
- "extensibility-request-implement"
- "extensibility-request-triage"
Comment thread
AleksandricMarko marked this conversation as resolved.
test-run:
description: "Indicate this is a test run (with few entries)"
required: false
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/copilot-evaluation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ on:
- "bug-fix"
- "test-generation"
- "code-review"
- "extensibility-request-implement"
- "extensibility-request-triage"
Comment thread
AleksandricMarko marked this conversation as resolved.
test-run:
description: "Indicate this is a test run (with few entries)"
required: false
Expand Down
4 changes: 2 additions & 2 deletions CATEGORIES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Adding a New Category

BC-Bench is **category-based**. A category is a distinct evaluation scenario: `bug-fix` asks an agent to patch buggy code, `test-generation` asks it to write reproduction tests, `code-review` asks it to flag issues in a diff, and `nl2al` asks it to turn a natural-language spec into AL code.
BC-Bench is **category-based**. A category is a distinct evaluation scenario: `bug-fix` asks an agent to patch buggy code, `test-generation` asks it to write reproduction tests, `code-review` asks it to flag issues in a diff, `nl2al` asks it to turn a natural-language spec into AL code, `extensibility-request-implement` asks it to implement an approved extensibility request (e.g. add an integration event) in an existing repo, and `extensibility-request-triage` asks it to triage an extensibility request (emit managed labels, an advisory comment, and an open/closed decision).

Categories also differ in how they're scored and run. `bug-fix` and `test-generation` are execution-based: they build and run AL code, so they need a BC container. `code-review` and `nl2al` both leverage LLM-as-a-judge: `code-review` scores precision/recall/F1 of flagged issues against expected findings (an LLM judge only matches comments), and `nl2al` has an LLM grade the output against an LMChecklist. The `EvaluationCategory` properties (`requires_container`, `runner`, `evaluators`, `core_score`) capture these differences for the workflows.
Categories also differ in how they're scored and run. `bug-fix` and `test-generation` are execution-based: they build and run AL code, so they need a BC container. `code-review`, `nl2al`, `extensibility-request-implement`, and `extensibility-request-triage` all leverage LLM-as-a-judge: `code-review` scores precision/recall/F1 of flagged issues against expected findings (an LLM judge only matches comments), and `nl2al`, `extensibility-request-implement`, and `extensibility-request-triage` have an LLM grade the agent output against an LMChecklist (for triage, the checklist encodes the expected managed labels, open/closed state, and the substance of the advisory comment). `extensibility-request-implement` and `extensibility-request-triage` are the first of a planned family of extensibility categories (a further sibling such as `ext-advisor` is not yet implemented). The `EvaluationCategory` properties (`requires_container`, `runner`, `evaluators`, `core_score`) capture these differences for the workflows.

Categories may share a dataset (`bug-fix` and `test-generation` do today), but a new category should generally have its own: dataset schema, entry type, result type, pipeline, etc.

Expand Down
23 changes: 23 additions & 0 deletions dataset/extensibility_request_implement.jsonl

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions dataset/extensibility_request_triage.jsonl

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Extensibility request: two integration events on page 7004 "Sales Line Discounts"

## Why do you need this change?

These event requests are related to an earlier case. In every request we will need the variable
`ItemTypeFilter` (currently an option, which we separately requested to change to an enum).

### 1. Procedure SetRecFilters

We need a new integration event in procedure `SetRecFilters`. We have extended page "Sales Line Discounts"
with additional fields backed by global variables. To properly control filtering and behavior, we need
access to the page instance (`var SalesLineDiscounts`) within the event, so we can implement
setter/getter procedures to read/write these global values during filter setup.

Existing events (e.g. `OnOpenPage` / `OnAfterGetRecord`) do not provide sufficient control during filter
application, and table triggers are not suitable since the required logic depends on page-level global
variables and UI state.

### 2. Procedure GetFilterDescription

Introduce a new integration event in procedure `GetFilterDescription()` to extend the `case ItemTypeFilter`
logic — specifically to handle additional/custom types (equivalent to an `else` branch). The current
implementation supports only predefined `ItemTypeFilter` values (Item, Item Discount Group) and offers no
extensibility point for additional/custom types. The event should allow overriding `SourceTableName`,
applying custom filtering logic on `Item`, and extending behavior without modifying base code.

## Describe the request

### 1. Procedure SetRecFilters

```al
procedure SetRecFilters()
begin
...
OnSetRecFilters(ItemTypeFilter, Rec, SalesLineDiscounts);
CurrPage.Update(false);
end;

[IntegrationEvent(true, false)]
local procedure OnSetRecFilters(ItemTypeFilter: Enum "Item Type Filter"; var SalesLineDiscount: Record "Sales Line Discount"; var SalesLineDiscounts: Page "Sales Line Discounts")
begin
end;
```

### 2. Procedure GetFilterDescription

```al
case ItemTypeFilter of
ItemTypeFilter::Item:
...
ItemTypeFilter::"Item Discount Group":
...
else
OnItemTypeFilterElse(ItemTypeFilter, SourceTableName, Item);
end;

[IntegrationEvent(true, false)]
local procedure OnItemTypeFilterElse(ItemTypeFilter: Enum "Item Type Filter"; var SourceTableName: Text; var Item: Record Item)
begin
end;
```

## Scope

- File: `SalesLineDiscounts.Page.al`
- This page exists only in the W1 base layer, so the change lives in W1 alone (no country/region layer
counterparts to propagate to).
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Extensibility request: IsHandled event before PrepareJobLine in codeunit 90 "Purch.-Post".PostItemJnlLineJobConsumption

## Why do you need this change?

We need an event before `InvoicePostingInterface.PrepareJobLine(...)` in order to be able to assign a
different value to the field "Qty. to Invoice" according to a particular custom condition, as well as run a
different custom procedure instead of `PrepareJobLine`. At the moment there are no alternative events to
skip the procedure `PrepareJobLine` or run a custom procedure instead when a condition based on custom
fields is satisfied.

### Why an IsHandled event is required

Under particular custom conditions based on extension fields, we must completely replace the standard
`PrepareJobLine` execution with a custom implementation and assign a different value to
`PurchLine."Qty. to Invoice"`. If the standard code continues to execute after our custom logic,
`PrepareJobLine` would run twice or would overwrite the values calculated by our customization. The existing
`OnPostItemJnlLineJobConsumption` / `OnPostItemJnlLineJobConsumptionOnBeforeJobPost` events are raised too
early, and the downstream `OnBeforePostJobOnPurchaseLine` event is raised after `PrepareJobLine` has already
run, so the hook is needed immediately before that call.

## Describe the request

In procedure `PostItemJnlLineJobConsumption` of codeunit 90 "Purch.-Post", raise a new `IsHandled` event
immediately before `InvoicePostingInterface.PrepareJobLine(...)`:

```al
if QtyToBeInvoiced <> 0 then begin
PurchLine."Qty. to Invoice" := QtyToBeInvoiced;
IsHandled := false;
OnBeforePrepareJobLinePrepareJobLine(IsHandled, PurchLine, QtyToBeInvoiced, PurchHeader, PurchLineACY);
if not IsHandled then
InvoicePostingInterface.PrepareJobLine(PurchHeader, PurchLine, PurchLineACY);
end;
```

```al
[IntegrationEvent(false, false)]
local procedure OnBeforePrepareJobLinePrepareJobLine(var IsHandled: Boolean; var PurchLine: Record "Purchase Line"; QtyToBeInvoiced: Decimal; var PurchHeader: Record "Purchase Header"; var PurchLineACY: Record "Purchase Line")
begin
end;
```

## Scope

- File: `PurchPost.Codeunit.al`
- This codeunit is present in 10 layers (W1, APAC, BE, CH, ES, FI, GB, IT, NA, RU), each keeping its own
copy. The identical change must be applied to all 10 layer files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Extensibility request: IsHandled event before RecreatePurchLines in table 38 "Purchase Header" (Pay-to Vendor No. validation)

## Why do you need this change?

We need an event inside the `OnValidate` trigger of field "Pay-to Vendor No.", to be able to run the
procedure `RecreatePurchLines` only if a custom `if` statement is satisfied or, alternatively, run a custom
procedure. Managing an `IsHandled` variable is the only way to skip `RecreatePurchLines` (when a particular
custom condition is satisfied) and run a custom procedure instead. At the moment there are no other ways to
do that.

### Why an IsHandled event is required

Some custom purchase lines contain additional information that must be preserved when the Pay-to Vendor
changes; executing the standard `RecreatePurchLines(PayToVendorTxt)` would remove or recreate lines in a way
that is not compatible with the custom business process. The extension needs to evaluate a custom condition,
skip the standard call when satisfied, and execute an alternative recreation procedure. The existing
`OnValidatePaytoVendorNoBeforeRecreateLines` event is raised immediately before the call but provides no
`IsHandled` parameter, and the generic `OnBeforeRecreatePurchLinesHandler` inside `RecreatePurchLines()`
is too late and too broad, so the decision must be made at the caller level in this specific validation.

The subscriber also needs `xRec` because the decision depends on comparing the document state before and
after the validation of "Pay-to Vendor No.".

## Describe the request

In the `OnValidate` trigger of field(4; "Pay-to Vendor No."; Code[20]) of table 38 "Purchase Header", raise
a new `IsHandled` event immediately before `RecreatePurchLines(PayToVendorTxt)`:

```al
if (xRec."Buy-from Vendor No." = "Buy-from Vendor No.") and
(xRec."Pay-to Vendor No." <> "Pay-to Vendor No.")
then begin
IsHandled := false;
OnBeforeRecreatePurchLines(IsHandled, Rec, xRec);
if not IsHandled then
RecreatePurchLines(PayToVendorTxt);
end;
```

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeRecreatePurchLines(var IsHandled: Boolean; var Rec: Record "Purchase Header"; xRec: Record "Purchase Header")
begin
end;
```

## Scope

- File: `PurchaseHeader.Table.al`
- This table is present in 14 layers (W1, APAC, BE, CH, DACH, ES, FI, GB, IT, NA, NL, NO, RU, SE), each
keeping its own copy. The identical change must be applied to all 14 layer files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Extensibility request: three extension points in table 39 "Purchase Line"

## Why this change is needed

Table 39 "Purchase Line" runs several pieces of standard logic that an extension currently cannot
skip or replace. In three places there is no event that lets a subscriber apply a custom condition
and, when it is met, run its own logic instead of the standard call:

1. In the `"Location Code"` field `OnValidate` trigger, `PlanPriceCalcByField` is always called for
items when the location changes; there is no way to suppress it conditionally.
2. In `CopyFromItem`, `GetItemTranslation` is always called when the purchase header has a language
code; there is no way to skip it and run custom translation handling instead.
3. In `CheckWMS`, `CheckLocationOnWMS` is always called when `CurrFieldNo <> 0`; there is no way to
suppress that warehouse check conditionally.

We need an extension point before each of these calls so subscribers can plug in custom handling in a
supported, upgrade-safe way.

## Requested change

Add three new integration events to table 39 "Purchase Line", each raised **before** the
corresponding standard call and each using the `IsHandled` pattern so a subscriber that sets
`IsHandled := true` skips the standard call:

1. Before `PlanPriceCalcByField` in the `"Location Code"` `OnValidate` trigger. Pass the
`Purchase Line` record, `IsHandled` (var), the current field number, and the `xPurchaseLine`
record.
2. Before `GetItemTranslation` in `CopyFromItem`. Pass the `Purchase Line` record, the `Item` record,
and `IsHandled` (var).
3. Before `CheckLocationOnWMS` in `CheckWMS`. Pass the `Purchase Line` record, the current field
number, and `IsHandled` (var). `CheckWMS` needs a local `IsHandled: Boolean` variable added.

Illustrative shape for one of the three (final event names and signatures must follow BC event
conventions):

```al
local procedure CheckWMS()
var
IsHandled: Boolean;
begin
IsHandled := false;
// new integration event raised here, passing Purchase Line, CurrFieldNo, and IsHandled (var)
if not IsHandled then
if CurrFieldNo <> 0 then
CheckLocationOnWMS();
// ...
end;
```

## Scope

- Table 39 "Purchase Line" is kept as a separate copy in many country/region layers. All three
events must be added consistently to **every** layer that keeps a copy of this table:
- `App/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al`
- and the same file in the APAC, BE, CH, DACH, ES, FI, GB, IT, NA, NL, NO, RU, and SE layers.
- That is 14 layer copies in total, so exactly 14 files change.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Extensibility request: OnBeforeOnRunOnCheckWarehouse event in codeunit 99000760 "Mfg. Item Jnl. Check Line"

## Why do you need this change?

We currently have two subscribers associated with the `OnRunOnCheckWarehouse` publisher event: one provided
by the standard Microsoft application and another implemented in our extension. When posting Consumption
transactions through our application, the warehouse validation logic executed in the local procedure
`OnRunOnCheckWarehouse` of codeunit 99000760 "Mfg. Item Jnl. Check Line" is preventing further processing,
as it is called by the MS standard event.

To handle this scenario, we require a handler event to conditionally bypass this validation logic for
transactions from our application. Providing an extensibility point (publisher event) within
`OnRunOnCheckWarehouse` would allow extensions to skip the standard validation when necessary, while
preserving the existing behavior for all other scenarios.

## Describe the request

Introduce a new publisher `OnBeforeOnRunOnCheckWarehouse` event at the start of procedure
`OnRunOnCheckWarehouse` that allows extensions to skip the standard validation logic when required, using
the `IsHandled` pattern with an early exit:

```al
IsHandled := false;
OnBeforeOnRunOnCheckWarehouse(ItemJournalLine, CalledFromAdjustment, CalledFromInvtPutawayPick, IsHandled);
if IsHandled then
exit;
```

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeOnRunOnCheckWarehouse(var ItemJournalLine: Record "Item Journal Line"; CalledFromAdjustment: Boolean; CalledFromInvtPutawayPick: Boolean; var IsHandled: Boolean)
begin
end;
```

## Scope

- File: `MfgItemJnlCheckLine.Codeunit.al`
- This codeunit exists in both the W1 base layer and the IT layer (which keeps its own copy). The identical
change must be applied to both the W1 and IT layer files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Extensibility request: OnBeforeUpdateSetupOnBillToCustomerChangeInSalesHeader event in table 36 "Sales Header"

## Why do you need this change?

We need to bypass the standard Microsoft logic in this procedure because we have a separate feature that
already handles the assignment of the VAT Registration No. and the relevant posting groups. Without an
`IsHandled` pattern, the Microsoft logic is always executed and may overwrite or conflict with the values
set by our own feature.

## Describe the request

Add an `OnBeforeUpdateSetupOnBillToCustomerChangeInSalesHeader` integration event before calling
`AltCustVATRegFacade.UpdateSetupOnBillToCustomerChangeInSalesHeader(Rec, xRec, BillToCustomer)` in procedure
`SetBillToCustomerAddressFieldsFromCustomer`. The event should provide an `IsHandled` parameter so
subscribers can skip the mentioned call when they handle the logic themselves.

```al
IsHandled := false;
OnBeforeUpdateSetupOnBillToCustomerChangeInSalesHeader(Rec, BillToCustomer, IsHandled);
if not IsHandled then
AltCustVATRegFacade.UpdateSetupOnBillToCustomerChangeInSalesHeader(Rec, xRec, BillToCustomer);
```

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateSetupOnBillToCustomerChangeInSalesHeader(var SalesHeader: Record "Sales Header"; BillToCustomer: Record Customer; var IsHandled: Boolean)
begin
end;
```

There are already three events in this procedure, but none lets me skip only the
`AltCustVATRegFacade.UpdateSetupOnBillToCustomerChangeInSalesHeader` call while keeping the rest of the
standard logic.

## Scope

- File: `SalesHeader.Table.al`
- This table is present in 15 layers (W1, APAC, BE, CH, CZ, ES, FI, FR, GB, IT, NA, NL, NO, RU, SE), each
keeping its own copy. The identical change must be applied to all 15 layer files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Extensibility request: add a temporary Warehouse Activity Line parameter to OnBeforeCreateWhseActivHeader in codeunit 7312 "Create Pick"

## Why do you need this change?

Add a parameter `TempWhseActivLine: Record "Warehouse Activity Line" temporary` as a `var` in the event
`OnBeforeCreateWhseActivHeader` of codeunit 7312 "Create Pick".

To support adding new items from an order to an existing warehouse pick for Sales Orders, Transfer Orders,
and Purchase Return Orders, we need access to a temporary instance of the Warehouse Activity Line record
during the pick creation process. Currently the `OnBeforeCreateWhseActivHeader()` event does not provide a
mechanism to pass or manipulate temporary warehouse activity lines. This will allow custom logic to prepare
and manage additional lines before the warehouse activity header is created.

## Describe the request

Enhance the existing `OnBeforeCreateWhseActivHeader` publisher signature by adding a
`var TempWhseActivLine: Record "Warehouse Activity Line" temporary` parameter, and pass the temporary
record instance when the event is raised in `CreateWhseActivHeader`:

```al
IsHandled := false;
OnBeforeCreateWhseActivHeader(CurrWarehouseActivityHeader, TempWarehouseActivityLine, LocationCode, FirstWhseDocNo, LastWhseDocNo, NoOfSourceDoc, NoOfLines, WhseDocCreated, IsHandled);
```

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateWhseActivHeader(var CurrWarehouseActivityHeader: Record "Warehouse Activity Header"; var TempWhseActivLine: Record "Warehouse Activity Line" temporary; LocationCode: Code[10]; var FirstWhseDocNo: Code[20]; var LastWhseDocNo: Code[20]; var NoOfSourceDoc: Integer; var NoOfLines: Integer; var WhseDocCreated: Boolean; var IsHandled: Boolean)
begin
end;
```

## Scope

- File: `CreatePick.Codeunit.al`
- This codeunit exists only in the W1 base layer, so the change lives in W1 alone (no country/region layer
counterparts to propagate to).
Loading
Loading