Skip to content
Merged
8 changes: 5 additions & 3 deletions .github/scripts/Test-SkillIndex.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,16 @@ try {
'microsoft/skills/review/al-query-review.md',
'microsoft/skills/review/al-reporting-review.md',
'microsoft/skills/review/al-appsource-review.md',
'microsoft/skills/review/al-telemetry-review.md'
'microsoft/skills/review/al-telemetry-review.md',
'microsoft/skills/review/al-scm-review.md',
'microsoft/skills/review/al-finance-review.md'
)
$review = @($skills | Where-Object id -eq 'al-code-review')
if ($review.Count -ne 1) {
throw "Expected exactly one al-code-review record, found $($review.Count)."
}
if ((@($review[0].subSkills) -join "`n") -cne ($expectedLeaves -join "`n")) {
throw 'al-code-review subSkills did not preserve the declared 17-leaf order.'
throw "al-code-review subSkills did not preserve the declared $($expectedLeaves.Count)-leaf order."
}
foreach ($leafPath in $expectedLeaves) {
$leaf = @($skills | Where-Object path -ceq $leafPath)
Expand Down Expand Up @@ -238,4 +240,4 @@ finally {
Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue
}

Write-Output 'Skill-index check PASSED: deterministic, schema-valid, and all 17 review leaves preserved in order.'
Write-Output "Skill-index check PASSED: deterministic, schema-valid, and all $($expectedLeaves.Count) review leaves preserved in order."
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<p align="left">
<img src="docs/assets/bcq-logo.svg" alt="BCQuality logo" width="300">
</p>
# BC Quality - Don’t teach one agent. Teach the ecosystem. 🤝

Quality skills and knowledge that help AI tools make better Business Central
development decisions: catch BC-specific defects, avoid misleading advice,
Expand Down Expand Up @@ -76,17 +74,20 @@ the review can still discover knowledge by reading the folders.

## Scope

Today's curated content focuses on **technical AL code review**. It augments
Today's curated content covers **technical AL code review** and a focused
**Supply Chain Management (SCM)** functional domain. It augments
the agent's judgment; it is not an exhaustive BC manual or a substitute for
compilation, analyzers, tests, or human review. See
[coverage and limits](docs/using-bcquality.md#coverage-and-limits) for the
available domains and the difference between a folder review and a comparison.
Mechanical issues already enforced by the AL compiler or standard analyzers are
intentionally left to those deterministic tools rather than duplicated here.

Functional areas such as Finance, Supply Chain Management, Manufacturing, Jobs,
Warehousing, and Service, and technologies such as PowerShell, pipelines, and
Power Platform, remain valid future scope, **not current coverage claims**.
The [SCM domain](microsoft/knowledge/scm/) covers selected inventory, costing,
reservation, tracking, and warehouse/posting workflows, not exhaustive supply
chain validation. Broader functional coverage such as Finance, Manufacturing,
Jobs, and Service, and technologies such as PowerShell, pipelines, and Power
Platform, remain valid future scope, **not current coverage claims**.

## What's in this repo

Expand Down
5 changes: 0 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
<p align="center">
<img src="assets/bcq-mark.svg" alt="BCQuality mark" width="128">
</p>

# BCQuality documentation

**New to BCQuality? Start with the [quick start](../README.md#quick-start).**
Expand Down Expand Up @@ -36,4 +32,3 @@ prerequisites for using the plugin.
| [DO](../skills/do.md) | Action-skill format and structured output contract. |
| [WRITE](../skills/write.md) | Knowledge-authoring rules. |
| [Review evaluation](../evaluation/README.md) | Sample conventions, fixture preparation, and scoring. |
| [Brand assets](brand-assets.md) | BCQ logo files and usage guidance. |
26 changes: 0 additions & 26 deletions docs/assets/bcq-logo.svg

This file was deleted.

22 changes: 0 additions & 22 deletions docs/assets/bcq-mark.svg

This file was deleted.

43 changes: 0 additions & 43 deletions docs/brand-assets.md

This file was deleted.

33 changes: 30 additions & 3 deletions docs/using-bcquality.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ branch names with ones in your project.
| Uncommitted changes | Use the installed al-code-review skill to review my staged and unstaged tracked changes against HEAD, without changing files. Identify any untracked AL files not included in that diff. |
| Branch changes | Use the installed al-code-review skill to review changes on this branch since its merge base with `origin/main`. Exclude uncommitted changes and do not edit files. |
| Focused review | Use the installed al-code-review skill to review performance in the app in this folder, without changing files. Return the complete performance findings report. |
| Supply chain code | Use the installed al-code-review skill to review SCM posting, inventory, reservations, item tracking, and warehouse workflows in this app folder, without changing files. Return the complete Supply Chain Management findings report. |
| Agent SDK code | Use the installed al-code-review skill to review Agent SDK implementation and usage in this app folder, without changing files. Return the complete Agents findings report. |

For Git comparisons, the named base ref must exist locally. If it is missing,
Expand Down Expand Up @@ -183,7 +184,7 @@ using your normal compilation, analyzer, test, and human-review workflow.

## Coverage and limits

The Microsoft broad review composes the 17 Microsoft domains listed below.
The Microsoft broad review composes the Microsoft domains listed below.
The Community Agents review is a separate skill selected by the request, not
a nested part of that coordinator. All current review leaves accept app
folders, files, and diffs; request an Agent SDK review explicitly when that
Expand All @@ -193,8 +194,32 @@ Available knowledge is **not** a promise that every rule will run. Selection
depends on the task, target context, enabled layers, and source evidence.
A whole-folder review is a current-state snapshot: detecting a published API
removal or another comparison-only regression requires an actual baseline.
The corpus is technical AL guidance, not exhaustive functional validation or
AppSource certification.
The corpus combines technical AL guidance with targeted functional-domain
invariants, not exhaustive functional validation or AppSource certification.

The SCM leaf owns selected inventory/value, application, reservation, tracking,
and warehouse/posting invariants. It prunes unrelated AL using the actual
tables, codeunits, fields, and operations in scope; an item caption or a broad
`ApplicationArea` alone is not an SCM review signal. Missing workflow context
must not be replaced with an assumed posting defect. Manufacturing, assembly,
planning, and other supply-chain areas are covered only where an article
explicitly names the shared interface or invariant.

SCM owns Item/Value/Capacity/Warehouse and inventory-application posting
records. Pure G/L, customer/vendor/detailed/VAT and financial-only posting
mutations belong to Finance, even when that domain is not enabled. Equivalent
findings for one inventory-originated posting bypass have one SCM primary
owner; distinct independent financial defects remain separate.

The Finance leaf reviews journal posting, financial ledger changes,
applications, and posting-linked dimension handling. It prunes unrelated code
at the leaf rather than changing broad-review orchestration. Finance articles
use `application-area: [all]` so missing application-area context does not
weaken applicable findings; resolved records and operations supply the
narrowing. Finance owns financial ledgers, not Item, Value, Capacity, Warehouse,
or inventory-application records owned by SCM. It also does not own generic
custom-table or master Default Dimension wiring. Request a focused "Finance
posting review" when only this domain is needed.

BCQuality intentionally does not duplicate mechanical diagnostics already
enforced by the AL compiler or standard analyzers. Run the consuming app's
Expand All @@ -215,13 +240,15 @@ Each article describes one concern. Where samples exist, use its linked
| Data modeling | [Data modeling](../microsoft/knowledge/data-modeling/) |
| Error handling | [Error handling](../microsoft/knowledge/error-handling/) |
| Events | [Events](../microsoft/knowledge/events/) |
| Finance | [Finance](../microsoft/knowledge/finance/) |
| Interfaces | [Interfaces](../microsoft/knowledge/interfaces/) |
| Performance | [Performance](../microsoft/knowledge/performance/) |
| Privacy | [Privacy](../microsoft/knowledge/privacy/) |
| Query objects | [Query](../microsoft/knowledge/query/) |
| Reporting | [Reporting](../microsoft/knowledge/reporting/) |
| Security | [Security](../microsoft/knowledge/security/) |
| Style | [Style](../microsoft/knowledge/style/) |
| Supply Chain Management | [SCM](../microsoft/knowledge/scm/) |
| Telemetry | [Telemetry](../microsoft/knowledge/telemetry/) |
| Testing | [Testing](../microsoft/knowledge/testing/) |
| User interface | [UI](../microsoft/knowledge/ui/) |
Expand Down
22 changes: 22 additions & 0 deletions evaluation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ The evaluation is convention-driven. The harness discovers every `<layer>/skills

Model-facing preparation hashes case IDs, neutralizes `Good`/`Bad` object-name tokens, and removes full-line sample comments so neither the article slug, domain, nor expected outcome reveals the answer.

The SCM `articles` override deliberately selects every rule in the initial
functional domain, producing nine positive cases and nine clean controls.
Business context is executable: document/status `TestField` guards,
calculated-revaluation fields, source-transfer base quantities, warehouse
reconciliation steps, and additional-demand promising parameters survive
neutralization. Do not move those preconditions into comments or generic
"posting" helper names; removing them can turn a real defect into a valid
alternative workflow. The clean pairs exercise the supported APIs selected by
the same routing cues, not merely unrelated code that contains no SCM tokens.

The Finance override deliberately covers every paired Finance article, not
only the first filename. Its shared context supplies the target version and
localization but deliberately omits application area, as production callers
often do. Finance applicability must come from its source-surface gate, not
an artificial evaluation-only area hint. Scenario prerequisites live in
executable AL: the document-balance cases check the template setting, and the
VAT cases encode the imported net/VAT/gross totals and applicable VAT mode.
Do not move these prerequisites into comments that preparation removes.
Clean samples also retain supported operational edits, temporary ledger/set
buffers, legitimate entry-number APIs, and reads of individual shortcut
dimensions so these exceptions are exercised rather than blanket-excluded.

## Validate the corpus

```powershell
Expand Down
32 changes: 31 additions & 1 deletion evaluation/review-fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
"events": {
"article": "reset-ishandled-only-when-the-value-can-carry-over"
},
"finance": {
"articles": [
"apply-ledger-entries-through-application-codeunits",
"change-ledger-due-dates-through-entry-edit",
"do-not-edit-shared-dimension-sets",
"do-not-modify-or-delete-posted-ledger-entries",
"normal-vat-journal-amount-includes-vat",
"post-ledger-entries-through-posting-codeunits",
"preserve-journal-batch-document-balance",
"reverse-transactions-by-transaction-number",
"write-dimensions-as-dimension-set-entries"
],
"context": "Target Business Central 28, worldwide standard application (w1). Review each file as an independent source input."
},
"interfaces": {
"article": "set-defaultimplementation-on-enum"
},
Expand Down Expand Up @@ -51,8 +65,24 @@
"stop-when-runrequestpage-returns-empty-parameters"
]
},
"scm": {
"articles": [
"post-item-ledger-changes-through-item-journals",
"post-revaluation-through-the-item-journal-batch",
"change-item-applications-through-posting-routines",
"cancel-reservations-through-reservation-management",
"transfer-item-tracking-through-source-reservation-codeunits",
"reconcile-warehouse-adjustments-with-the-item-ledger",
"post-transfers-through-shipment-and-receipt-codeunits",
"use-date-aware-availability-for-promising",
"carry-out-requisition-actions-through-the-standard-workflow"
]
},
"style": {
"article": "label-comment-explains-placeholders"
"articles": [
"label-comment-explains-placeholders",
"dateformula-evaluate-needs-language-independent-literals"
]
},
"telemetry": {
"article": "telemetry-event-id-stable-unique"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
table 50603 "Sample Order Header Bad"
{
fields
{
field(1; "No."; Code[20])
{
DataClassification = CustomerContent;
}
field(2; "Document Date"; Date)
{
DataClassification = CustomerContent;
}
}

trigger OnInsert()
var
SalesSetup: Record "Sales & Receivables Setup";
NoSeries: Codeunit "No. Series";
begin
"Document Date" := WorkDate();

if "No." = '' then begin
SalesSetup.Get();
SalesSetup.TestField("Order Nos.");
"No." := NoSeries.GetNextNo(SalesSetup."Order Nos.");
end;
end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
table 50602 "Sample Order Header Good"
{
fields
{
field(1; "No."; Code[20])
{
DataClassification = CustomerContent;
}
field(2; "Document Date"; Date)
{
DataClassification = CustomerContent;
}
}

trigger OnInsert()
var
SalesSetup: Record "Sales & Receivables Setup";
NoSeries: Codeunit "No. Series";
begin
if "No." = '' then begin
SalesSetup.Get();
SalesSetup.TestField("Order Nos.");
"No." := NoSeries.GetNextNo(SalesSetup."Order Nos.");
end;

InitRecord();
end;

procedure InitRecord()
begin
OnBeforeInitRecord(Rec);
"Document Date" := WorkDate();
OnAfterInitRecord(Rec);
end;

[IntegrationEvent(false, false)]
local procedure OnBeforeInitRecord(var SampleOrderHeader: Record "Sample Order Header Good")
begin
end;

[IntegrationEvent(false, false)]
local procedure OnAfterInitRecord(var SampleOrderHeader: Record "Sample Order Header Good")
begin
end;
}
Loading
Loading