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
Merge current main because it added four active AL review leaves, then extend the findings domain contract across all 15 leaves, generic composition guidance, plugin documentation, and the self-review knowledge-upgrade path.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 77d0a40e-8bf5-40ac-a450-40eb0255db03
Repair broken knowledge references and align review examples with canonical articles. Correct explicit version gates, restore a missing title, and recognize the plugin directory in the root guard.
Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Package BCQuality as an installable plugin (experiment)
Adds a marketplace + plugin manifest and a bridge review skill that drives the existing Entry protocol from a plugin host. No changes to knowledge or routing logic.
* Bridge skill: make enabled-layers configurable; note layer-pruning limit and manifest choice
Addresses PR #84 review (JesperSchulz): #2 layer policy has no hook in the plugin path -> expose BCQUALITY_ENABLED_LAYERS and document that it narrows discovery only, not a hard deny; #3 document the .claude-plugin manifest choice (verified on Copilot CLI).
---------
Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
The /custom/ layer is a template: in upstream microsoft/BCQuality it stays
empty by default and is meant to be populated only inside a fork or consumer
clone. PR #55 both targeted /custom/ and leaked a new top-level folder.
- skills/write.md: add a fork-precondition guard so authors (human or agent)
confirm they are not in microsoft/BCQuality before scaffolding /custom/ content.
- Guard custom layer workflow: auto-closes upstream PRs that add/modify /custom/
content beyond the template files, with a friendly redirect-to-fork comment.
- Flag new top-level entries workflow: posts an advisory (non-blocking) comment
when a PR introduces an unexpected top-level folder or file for maintainer review.
Both workflows run only on microsoft/BCQuality (never on forks) and read the PR
file list via the API without checking out or executing PR code.
Co-authored-by: Jeremy Vyska <jeremy@sparebrained.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
Action skills emit AL source in message/suggested-code fields. Quoted
identifiers and multi-line snippets must have their embedded quotes and
newlines escaped, otherwise the consumer JSON parse fails and silently
drops the report. Add a JSON validity subsection to the output contract
making the escaping requirement explicit.
Co-authored-by: wenjiefan <wenjiefan@microsoft.com>
A closed range like [23..28] wrongly implies guidance stops applying after
BC28, so a reviewer targeting BC29+ would not match the file. Introduce an
open-ended shorthand [N..] meaning ''version N and every later version''.
- validate_frontmatter.py: RANGE_SHORTHAND allows an optional upper bound;
expand_bc_version returns the normalized string ''N..'' for open-ended.
- read.md: document the fourth bc-version form and its matching rule
(matches target >= N; not enumerable).
- write.md: prefer [N..] over a closed range for a feature introduced in N
and not expected to be removed.
- Apply [23..] to the actionable-errors article (actionable errors shipped
in BC23 and are not version-bounded above).
- README: mention [N..] in the frontmatter example.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Make domain-skill knowledge discovery index-aware
The 6 AL domain review skills and read.md now enumerate candidate articles
from the BCQuality knowledge index (knowledge-index.json) instead of opening
every file under the domain folder to read its frontmatter. The worklist
selection predicate is unchanged (keywords intersect diff tokens, or topic
matches a changed object type) - only the discovery source changes, so the
same articles are selected. Full article bodies are read only for worklisted
entries.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Reconcile §Source wording with the lean knowledge index
The BCQuality filter now emits a lean index whose per-article description is a
one-line hint rather than the full verbatim Description. Update the six domain
skills' §Source to say the index carries a one-line description hint (keywords,
title, and a one-line description) instead of the full description. The
worklist selection predicate is unchanged: keywords drive selection and the
agent opens worklisted articles in full for their rule bodies.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Own the knowledge-index generator in BCQuality
The knowledge index is an acceleration of the skills' Source step, and its
schema is part of that contract — so BCQuality should own the generator rather
than each consumer re-implementing it. Add tools/Build-KnowledgeIndex.ps1 (the
parser + lean-description shaping + emit, lifted verbatim from the
BCAppsBCQuality filter prototype) and document the index in agent-consumption.md.
Consumers prune their clone to policy, then call this script; the index stays
in lockstep with the Source contract and every orchestrator gets the same
faithful index for free. The worklist selection predicate is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Own knowledge-index generation in BCQuality (runtime + CI), not the consumer
The index is now produced by BCQuality itself: Entry's preparation step
rebuilds knowledge-index.json over the live, already-pruned clone at the start
of every run, and a new CI workflow validates the generator's health
(determinism, full coverage, selection-input integrity). Consumers no longer
invoke or know about the index.
Rebuilding over the pruned clone (vs shipping a committed full-corpus index)
keeps the index exact for any consumer policy: it can never list a denied
article, so policy-excluded rules cannot leak into discovery. READ now states
the index is discovery-only -- a finding must cite an article opened in full,
and rows whose file is absent are discarded before ranking.
- skills/entry.md: new 'Preparation -- knowledge index' precondition
- skills/read.md: index ownership + discovery-only invariant
- microsoft/skills/review/*.md (6): 'BCQuality builds' (not 'the filter emits')
- agent-consumption.md 5a: runtime+CI ownership rationale
- .github/workflows/knowledge-index.yml + scripts/Test-KnowledgeIndex.ps1: generator guard
- .gitignore: never commit the runtime index
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Make runtime index build non-interactive and self-contained
entry.md now gives the exact build command (pwsh ./tools/Build-KnowledgeIndex.ps1)
so the agent's preparation step is unambiguous, and the generator's -BCQualityRoot
parameter is optional (defaults to the clone root) so it runs in non-interactive
-p mode without prompting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Resolve knowledge-index root to absolute path (cross-platform fix)
Get-ChildItem.FullName is always absolute, so deriving the relative article
path via Substring(\.Length) requires an absolute root. A relative root
such as '.' (used by the CI guard's 'Test-KnowledgeIndex.ps1 -Root .') left the
full path almost intact on Linux, producing bogus 'home/runner/.../knowledge'
paths and failing the coverage check. Normalise both the generator's
-BCQualityRoot and the test's -Root with Resolve-Path before use.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Agent findings (model-judgment findings not backed by a curated knowledge
file) were producing too many false positives. Raise their emission bar and
make them advisory:
- skills/do.md: add a canonical 'Precision bar' for agent findings (emit only
concrete, material defects an expert would agree on; steelman first; an
explicit never-emit list; 'when in doubt, omit') and cap agent-finding
severity at minor (advisory, non-gating), with a promotion note for
severe-but-uncovered concerns.
- al-code-review.md: decouple the mandatory self-review reasoning from output
so emitting zero agent findings is a valid outcome; add the severity cap.
- Six leaf review skills: add the per-domain precision bar and severity cap
(style leaf gets domain-appropriate wording).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BCQ now wins on coverage in the synthetic complex benchmark, but only
2 of 25 rendered comments carried GitHub suggestion blocks while the
AIRHack reviewer emitted suggestions for every finding. Tighten the
DO contract and leaf-skill instructions so suggested-code is no longer
a soft affordance for mechanical fixes.
Changes:
- Add optional findings[].suggested-code-omission-reason to the DO
schema.
- Document suggested-code as expected for small, local, mechanical
findings, with examples (delete unreachable code, Count() > 0 ->
not IsEmpty(), move local Label, add missing ToolTip/OptionCaption,
replace string-concatenated Error, change permission token, add an
obvious else/guard branch).
- Require omission reasons when a mechanical-looking finding omits
suggested-code.
- Update all AL leaf skills and al-code-review guidance with the same
stronger contract.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The original DO contract pinned all agent reasoning to the super-skill:
'Agent findings are emitted only by super-skills... Leaf sub-skills MUST
NOT emit agent findings'. This funnels all agent reasoning across all 6
domains through a single super-skill pass, which is the root structural
cause of the attention dilution we have been chasing in BCAppsBCQuality
PRs #28 and #30:
- T1 standalone run showed al-security-review finds rimd-on-read-only
cleanly when run alone, but emits zero agent findings because the
contract forbids it. So obvious things like case-without-else (no
matching KB article yet) get dropped on the floor.
- The al-code-review self-review pass keeps producing 0-1 agent findings
per PR because it is asked to reason across 6 domains in one pass.
The fix is to move agent reasoning into the leaves, bounded by each
leaf's domain. Each leaf now has both knowledge-backed and agent-finding
permissions within its own scope; the super-skill self-review pass
becomes a smaller, cross-cutting role.
skills/do.md
- Replace the 'only by super-skills' / 'MUST NOT' clause with a
two-tier model: leaf sub-skills MAY emit agent findings strictly
within their declared domain; super-skills MAY emit agent findings
for cross-cutting concerns that span domains.
- Update the encoding rules: leaf agent findings have references:[]
and an agent:-prefixed id, no from-sub-skill (the leaf's own report
carries the finding under its own skill.id). Super-skills set
from-sub-skill='agent' for their own self-review findings; when
rolling up leaf agent findings, they set from-sub-skill=<leaf-id>.
- Clarify that 'MUST validate against knowledge' applies to super-
skill self-review candidates only - leaves already validated within
their domain when they decided to emit.
microsoft/skills/review/al-{security,performance,privacy,style,upgrade,
ui}-review.md
- New paragraph after the confidence rules instructing each leaf to
surface domain-specific agent findings when no knowledge file
covers a defect the agent recognises from general AL knowledge.
- Bound the scope: 'The scope is strictly <domain>; defects outside
this domain belong to other leaves and MUST NOT be emitted here.'
- Same validation requirement: check the worklist for a matching
knowledge file first; if one exists, upgrade to a knowledge-backed
finding instead.
microsoft/skills/review/al-code-review.md
- Rewrite the 'Agent self-review pass' subsection. The pass is now
explicitly for cross-cutting concerns that no single leaf could
have surfaced because they span multiple domains. Domain-specific
reasoning belongs in the leaves, not duplicated here.
- Update the rollup behavior to acknowledge leaf-emitted agent
findings: they are rolled up like any other sub-skill finding, with
from-sub-skill set to the leaf id, and are not re-validated by the
super-skill (the leaf already validated within its own domain).
- Drop the 'Leaf sub-skills MUST NOT emit agent findings' line.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the contract field, skill instructions, and two knowledge articles
that BCAppsBCQuality's PR-review agent needs to match (and exceed) the
coverage of the embedded review agent in BCAppsCampAIRHack:
skills/do.md
- New optional findings[].suggested-code field. Documents what it MUST
contain (a literal line-replacement payload) and when to emit it.
microsoft/skills/review/al-code-review.md
- Instructs both the agent self-review pass and rolled-up sub-skill
findings to populate suggested-code when the fix is mechanical.
- Lists examples (dead code removal, Count > 0 -> IsEmpty, object-scope
Label) that map to issues observed in the parity comparison.
microsoft/knowledge/style/telemetry-event-id-stable-unique.{md,bad.al,good.al}
- New knowledge article: telemetry event IDs must be stable, unique,
and non-placeholder. Closes a gap surfaced by the parity comparison.
microsoft/knowledge/style/labels-declared-at-object-scope.{md,bad.al,good.al}
- New knowledge article: Labels must live in the object-level var
block, not in procedure-local var blocks. Closes the second gap.
microsoft/knowledge/privacy/no-pii-in-telemetry-message-string.md
- Adds an explicit note that changing DataClassification alone does not
make embedding PII into the message string acceptable, plus links to
the two adjacent privacy articles. Resolves the privacy advice the
parity comparison flagged as ambiguous.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Let super-skills surface findings the agent identifies on its own,
clearly tagged so consumers can render them differently from
knowledge-backed ones.
- skills/do.md: permit references:[] when from-sub-skill='agent';
define the agent-finding encoding (id 'agent:<slug>', confidence
capped at medium, self-contained message); restrict agent findings
to super-skills only.
- microsoft/skills/review/al-code-review.md: add a self-review pass
to Action that validates agent-identified candidates against
BCQuality (cite if matched, suppress if contradicted, surface as
agent finding otherwise). Add example finding.
- agent-consumption.md, README.md: describe the additive model and
the from-sub-skill: 'agent' marker so consumer orchestrators know
to render unbacked findings.
Strictly additive: existing knowledge-backed flow is unchanged and
backward compatible.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The knowledge corpus now covers performance, security, privacy, upgrade,
style, and UI. Previously only two leaf reviewer skills existed
(al-performance-review, al-security-review), so four of the six domains
had knowledge with no skill sourcing from them. A community reader
landing in privacy/, upgrade/, style/, or ui/ would see articles with
no apparent consumer.
Three changes:
1. Move existing review skills into `microsoft/skills/review/`. The
`review/` subfolder groups all review-kind skills together and leaves
room for future non-review action skills at the `microsoft/skills/`
level. Updates references in README.md, agent-consumption.md, and
skills/entry.md to the new paths.
2. Add four new leaf reviewer skills — al-privacy-review,
al-upgrade-review, al-style-review, al-ui-review — each following
the same DO template as al-performance-review/al-security-review but
sourcing from the corresponding knowledge domain. al-upgrade-review
and al-ui-review return `not-applicable` when the diff contains no
upgrade surface or no page files, respectively.
3. Update al-code-review to compose all six leaf skills and retarget
the dangling references in every populated JSON example
(`use-setloadfields.md`, `no-plaintext-secrets-in-telemetry.md`,
`avoid-implicit-commit.md` — none of which exist in the corpus) to
real knowledge files: `call-setloadfields-before-filters.md`,
`use-secrettext-for-credentials.md`, `never-hardcode-secrets-in-al.md`.
Validator passes with 0 errors / 0 warnings.
Most of the corpus — FindSet/SetLoadFields/CalcFields patterns, permission
sets, SingleInstance codeunits, DataClassification, IsolatedStorage,
transaction scope, SecretText — describes BC platform behaviour that is
identical across supported versions. The seed [26..28] range on every
file implied a version-specificity the content does not actually have,
and there was no way to express "applies to every version" in the
schema the way [w1] and [all] already do for countries and
application-area.
Extend the v1 schema with a universal sentinel for bc-version, parallel
to the sentinels already defined for the other dimensions:
bc-version: [all] # applies to every BC version
[all] is mutually exclusive with explicit versions. Range shorthand
([26..28]) and explicit lists ([26, 27, 28]) continue to work for files
genuinely tied to a version-gated API or deprecation.
Update read.md (field definition, matching semantics, partial-context
rule), write.md (default to [all], use ranges only with a concrete
reason), README.md (frontmatter example), and the CI validator. All
forty existing knowledge files and the three action skills convert to
[all]; none of the current content is version-gated. Validator passes.
Add a new skill kind, 'entry-point', and its sole instance at
skills/entry.md. When an orchestrator points an agent at BCQuality,
the agent's first call is Entry: it receives a task context and
returns a dispatch record naming the action skill(s) to invoke.
Routing logic lives in Entry, not in the orchestrator.
Entry structurally follows DO's Source -> Relevance -> Worklist ->
Action pattern but the units it selects are action skills (not
knowledge files) and its output is a dispatch record (not a
findings-report).
Contract highlights:
- Inputs semantics in DO clarified as any-of: orchestrator supplies
whichever listed input types it has; skill must return
'not-applicable' if the subset is insufficient. This matches
the existing al-* canonical skills which declare
[pr-diff, file-path] as alternatives.
- Relevance admits candidates whose inputs intersect
inputs-available, not whose inputs are a subset.
- Dispatched inputs are the intersection, not the full
inputs-available set, to avoid leakage between skills.
- Super-skill precedence in Worklist supersedes a sub-skill only
when the goal is a broader match for the super than the sub.
When the goal specifically names a concern the sub handles
(e.g., 'performance review'), the sub wins and the super is
dropped with reason 'narrower-sub-skill-selected'.
- Skill layer precedence is defined here as custom > community >
microsoft, matching READ's rule for knowledge files.
- skipped[] carries 'superseded-by' for layer-precedence,
sub-skill, and super-skill drops, for traceability.
Propagate the concept through:
- skills/README.md: distinguish the runtime entry-point skill from
the three meta-skill contracts.
- skills/do.md: acknowledge entry-point alongside meta-skills as
the only kinds that live outside a layer.
- README.md: rewrite the Skills and Agent bootstrapping sections
so the bootstrap instruction is 'invoke /skills/entry.md first'.
- agent-consumption.md: update the Mermaid flow and step narrative
to show Entry dispatch, with READ and DO read on demand.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Anyone (human or agent) browsing to /skills/ on GitHub previously saw a
bare directory listing. This file names the three meta-skills, states
the reading order, and describes who each is for. Replaces the
placeholder .gitkeep.
No contract changes -- this is a navigation aid.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sample code in knowledge articles is demonstration-only and never
imported into a BC app, so object-ID uniqueness or ranges are not a
property the READ contract needs to enforce. The Sample files section
now just says samples are self-contained and demonstration-only, with
no guidance about IDs.
Existing samples keep whatever IDs they happen to have; future authors
are free to use anything readable.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The /samples/ top-level tree is replaced with sibling files in each
knowledge-layer folder. An article and its demonstrations now live
side-by-side:
microsoft/knowledge/<domain>/<slug>.md
microsoft/knowledge/<domain>/<slug>.good.al
microsoft/knowledge/<domain>/<slug>.bad.al
Rationale:
- Proximity. An article and its paired samples are one unit; the
filesystem now reflects that.
- Layer ownership. Samples inherit layer precedence for free -- a
/custom/ fork can override an article and its samples atomically,
which the shared /samples/ tree previously made awkward.
- Trivial migration path. Action-skill source globs
(*/knowledge/<domain>/**/*.md) are unchanged; sample discovery is a
sibling-filename lookup.
Changes:
- git mv of all 65 sample files from samples/<domain>/<slug>/{bad,good}.al
to microsoft/knowledge/<domain>/<slug>.{bad,good}.al (history preserved).
- Update See-sample references in all 37 articles that ship samples.
- skills/read.md: replace the no-code-blocks bullet with a pointer to a
new Sample files section that fully specifies the sibling convention,
the kinds (good/bad + forward-compatible), multi-technology rules,
demonstration-only status, and layer-precedence behaviour.
- skills/write.md: update the samples pointer to match.
- README.md: annotate the knowledge tree with the sample sibling shape.
- samples/README.md deleted; content lifted into skills/read.md.
- Both generators (C:\temp\gen_performance_knowledge.py,
C:\temp\gen_security_knowledge.py) updated to emit at the new paths
and to stop writing samples/README.md. Re-running them is idempotent
against the committed layout.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DO contract (skills/do.md)
- New 'sub-skills' optional frontmatter field on action skills: when
present and non-empty, the skill is a super-skill that composes
other action skills.
- New 'Composition (super-skills)' section covering section
interpretation, outcome rollup, summary aggregation, and suppression
scope.
- Output schema gains three optional fields: 'from-sub-skill' on each
finding, top-level 'sub-results[]' carrying nested findings-reports,
and top-level 'skipped-sub-skills[]'.
- Super-skills MUST NOT filter sub-skills by task content; leaves own
task-level applicability and signal via outcome.
- Findings from a failed sub-skill MUST NOT flow into the parent's
findings[] or counts, consistent with DO's rule that consumers
ignore a failed skill's findings. Reports are still preserved in
sub-results[] for traceability.
- Rolled-up non-citation finding ids MUST be prefixed with the sub-
skill id to prevent collisions across sub-skills. Citation-based
ids are already unique via repo path and are not rewritten.
- Outcome rollup rules updated: 'partial' covers S = {partial},
{partial, partial}, and {partial, failed}. Empty worklist rolls up
to 'not-applicable' with outcome-reason.
- Nested super-skills are not permitted in v1.
Reference skills (microsoft/skills/)
- al-code-review.md rewritten as the canonical super-skill: lists
al-performance-review and al-security-review as sub-skills, orch-
estrates invocation, aggregates output, and includes a worked
rolled-up JSON example plus the empty-corpus rollup.
- al-performance-review.md added as a leaf reference skill for the
performance knowledge domain.
- al-security-review.md added as a leaf reference skill for the
security knowledge domain.
- Both leaves retain the leaf-level rules validated in the prior
pass: partial-context message requirement, worklist-scoped
suppression, application-area semantics, and the platform-guarantee
threshold for blocker severity.
README updated to describe leaf vs super-skill and link all three
reference skills.
Two rubber-duck passes tightened the contract and caught schema
violations in the worked examples before commit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- skills/read.md (READ, Schema + Use) — knowledge-file contract:
frontmatter schema, required/optional sections (normative vs
non-normative), layer precedence with applicability-based conflict
detection, explicit frontmatter matching semantics (including
partial-context handling).
- skills/do.md (DO, Action Skill) — action-skill template:
frontmatter schema, required sections, four-step pattern
(Source -> Relevance -> Worklist -> Action), and the output contract
as a JSON schema with outcome, findings, structured references,
confidence, and mandatory suppression recording. Includes a worked
example.
- skills/write.md (WRITE, New Knowledge) — authoring guide:
atomicity, size, section guidance, field-by-field choices, file
naming, layer choice, pre-PR checklist. Defers to READ for the
format spec.
- README.md — link the three files from the meta-skills section and
update the output-contract paragraph to include outcome and
suppressed.
- agent-consumption.md — update step 5 (Agent emits structured output)
to match the richer DO contract.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>