Skip to content

Give Your AL Review Agents a Source They Can Cite

How we wired BCQuality into ALDC and turned «trust me» reviews into falsifiable ones.

Anyone who has pointed an LLM at an AL pull request has met the same two failure modes. It flags problems that aren’t there. It misses problems that are. And on the days it gets the answer right, it cannot explain why in a way you can verify. The reasoning is buried in a prompt that drifts with every model release and cites nothing.

ALDC — our AL Development Core, a small constellation of Copilot agents (@al-architect, @al-conductor, @al-developer) wired together with skills, subagents and auto-applied instructions — had this exact gap. The review subagent ran a competent checklist. The checklist was self-evident. «Missing SetLoadFields» with no authority behind it is an opinion, not a finding.

What we wanted was a review that points at a source a human can open. That source turned out to exist already: BCQuality, Microsoft’s curated, machine-readable knowledge base for Business Central. This article is the integration pattern we used. It is BC-specific in the examples, but the shape — citable knowledge base, thin consumption contract, structured findings, CI that validates citations — generalises to any AI-assisted review pipeline.

Why BCQuality is the right ground truth

BCQuality is not another style guide and that distinction matters. Its admission test is unusually sharp: a file exists only if a capable LLM would get something wrong without it. «Use HTTPS» does not qualify because every model already knows it. «SetLoadFields must be called before filters, not after» does qualify, because it is a non-obvious ordering rule, specific to Business Central, that models routinely invert.

Each rule is an atomic markdown file with YAML frontmatter — bc-version, domain, technologies, countries, application-area — and normative ## Best Practice and ## Anti Pattern sections. Code samples live in sibling .al files. Every file has a stable, repo-relative path, which is the load-bearing detail: an agent can cite it.

The consumption model is a small contract. An orchestrator points the agent at BCQuality with one instruction: invoke /skills/entry.md first. entry.md routes to an action skill; the canonical one, al-code-review, composes six leaf skills covering performance, security, privacy, upgrade, style, and UI. Each skill follows the same four steps — Source, Relevance, Worklist, Action — and emits a single JSON findings-report. Every finding carries severity, confidence, and references[] pointing back to the file that justifies it.

Framing it as a citation layer, not a rewrite

The first design choice was the one that mattered most. BCQuality is an additive citation layer, not a replacement for what ALDC already does. The auto-applied instructions still enforce rules at generation time. The native checklist still runs. BCQuality sits alongside them and provides citable findings on top. Nothing was torn out.

To make reviews reproducible we vendored BCQuality as a pinned git submodule at .bcquality/. The same review cites the same knowledge at the same commit, forever. Bumping the version is a deliberate commit, not a silent drift. Then we gave the review subagent a «Step 0»: before its own checklist, consult BCQuality through the contract.

Three lessons from the integration

Omit, do not fake. The most expensive bug we hit was honest-looking and wrong. BCQuality’s matching semantics treat an omitted frontmatter dimension as unknown, not as «matches everything». Our first task-context hardcoded application-area: [all] and countries: [w1] for convenience. That silently over-matched rules and inflated finding confidence. The leaf skills are explicit about this — «pass the actual set; do not substitute [all]«. The fix was to derive bc-version and area from app.json and the changed objects, and omit anything the agent cannot determine. The contract then caps unknown-matched findings at medium confidence, which is exactly the right epistemic floor. The general principle: when consuming a knowledge contract, follow its semantics literally, especially on the «I don’t know» path.

Let the knowledge base own its domains. Once BCQuality covered performance, security and style, our native checklist was duplicating it. We split the checklist in two: consume from BCQuality for performance, naming, error handling, secrets and permissions; keep native checks only for what BCQuality’s pilot doesn’t yet reach — no base-object modification, AL-Go project structure, test coverage, feature-based folders. A conditional fallback re-activates a native check when BCQuality returns no-knowledge for that domain. The rule «BCQuality first, native only for the residual» keeps the two layers from fighting and shrinks our maintenance surface as BCQuality grows.

JSON is the source of truth, markdown is a render. The review subagent emits a single structured review-report JSON, reusing BCQuality’s findings-report shape. Native findings carry source: "native" and a citation to the ALDC instruction that defines them. The orchestrator gates on the JSON deterministically — it recomputes the verdict from severity counts rather than parsing prose — and then renders the human-readable review from the same JSON. Two channels, two audiences: machines read the structure, people read the markdown.

What a cited finding looks like

{
"source": "bcquality",
"severity": "major",
"message": "FindSet is called without a prior SetRange/SetFilter — full table scan.",
"location": { "file": "App/Sales/Recalc.Codeunit.al", "line": 7 },
"references": [
{ "path": "microsoft/knowledge/performance/filter-before-find.md" }
],
"confidence": "high"
}

A reviewer — human or agent — can open filter-before-find.md at the pinned commit and confirm the rule says what the finding claims. That is the point: the review is falsifiable. We lean into this with a CI check that extracts every citation from the persisted reports and asserts the path resolves to a real file inside the submodule. A hallucinated citation fails the build. It does not prove the reasoning was sound, but it closes the made-up source gap, which is most of the trust problem.

An independent auditor on top

The in-loop reviewer trusts the developer’s context. We also wanted a neutral second opinion, so we added an independent agent — codename Dredd — that audits the codebase on demand, outside the TDD cycle. By default it scopes to objects changed against main. It reuses the same BCQuality contract and the same JSON shape (wrapped in an audit envelope), ignores any self-declarations from the developer, and judges the artifact alone. Same knowledge, same citations, different authority. We will write that one up separately.

The generalisable shape

Strip away the BC specifics and the pattern reduces to five moves that any team building AI-assisted review can copy:

A citable knowledge base of atomic, remedial rules, each with a stable path. A thin consumption contract — route, read, do — so agents and the knowledge evolve independently. Agents that consume the knowledge as a layer, not a replacement for existing enforcement. Structured output with citations, rendered for humans but gated by machines. A CI check that validates citations against the source, making «I used the knowledge» falsifiable.

For Business Central teams specifically: BCQuality is in public preview and worth watching closely. A shared, community-curated quality bar that your tooling can cite is a fundamentally different artifact from a prompt that asserts. The integration took a few careful steps and one good bug. The payoff is reviews that no longer ask you to take their word for it.

References

  • BCQuality repository — https://github.com/microsoft/BCQuality
  • BCQuality consumption contract — /skills/entry.md in the repo
  • ALDC framework on the VS Code Marketplace
  • Findings-report schema — see microsoft/knowledge/_schema/ in BCQuality

Closing

If your review agent cannot show you the receipt, the verdict is an opinion. Citable knowledge plus a CI that validates the citations is what turns an opinion into a finding. The infrastructure is there. The pattern is portable. The bug list is now public.

jarmesto originally posted this article on 20 August 2026 at 7:53 AM.

Leave a Reply