skill-diagnostics
Purpose
Perform a static audit of an AL workspace against the project's
copilot-instructions.md contract. Produce a structured report of findings.
Report only. Never modify source code. Never invent rules that are not
declared in the contract.
When to load
Load this skill when the user asks you to:
- Audit the workspace / run a compliance check / scan for issues
- Review the code before a PR / before a release
- Diagnose why a new file does not match project conventions
- List all violations of the
copilot-instructions.md contract
- Generate a contract-drift report
Input expectations
- Repository contains
.github/copilot-instructions.md (required · if missing,
emit a Blocker finding and continue with a reduced rule set)
- Workspace contains one or more AL projects with
app.json
- Optional: test folder(s) declared in AL-Go
settings.json under testFolders
Finding classes
Group every finding into exactly one of four classes:
| Class |
What it covers |
| Compliance |
Object prefix, ID range, DataClassification, Caption/ToolTip presence |
| Code quality |
XML docs, explicit Access, prohibited patterns, style ordering |
| Test coverage |
Missing test codeunits, public procedures without tests |
| Permissions |
Objects missing from permission sets |
Severity scale
| Severity |
Meaning |
Rule of thumb |
| Blocker |
Breaks contract at a fundamental level · must fix before merge |
Missing DataClassification, ID out of range, no permission set entry |
| Major |
Violates a required pattern declared in the contract |
Missing Caption/ToolTip, public procedure without XML doc |
| Minor |
Style deviation or soft convention |
Wrong section order, hardcoded numeric ID in code |
| Nit |
Noise-level observation · safe to ignore |
Inconsistent indentation within a file |
If in doubt between two levels, downgrade. A noisy Blocker-heavy report
erodes trust. Reserve Blocker for things that would fail review hard.
Rule catalogue · the ~20 rules this skill checks
Rules map 1:1 to statements in copilot-instructions.md. If a rule is not
declared in the contract, do not check it.
Compliance (7 rules)
| # |
Rule |
Severity |
Source in contract |
| C1 |
Every new object name starts with the declared prefix |
Major |
"Object prefix" |
| C2 |
Object IDs fall inside the declared idRanges of app.json |
Blocker |
"ID Range" |
| C3 |
Every table has DataClassification at object level |
Blocker |
"Required Patterns · Tables" |
| C4 |
Every table field has Caption |
Major |
"Required Patterns · Tables" |
| C5 |
Every table field has ToolTip (except PK of lookup tables) |
Major |
"Required Patterns · Tables" |
| C6 |
Every page has ApplicationArea and UsageCategory |
Major |
"Required Patterns · Pages" |
| C7 |
Every enum declares Extensible = true; unless exception documented |
Minor |
"Required Patterns · Enums" |
Code quality (8 rules)
| # |
Rule |
Severity |
Source in contract |
| Q1 |
Public procedures have XML documentation (///) |
Major |
"Required Patterns · Codeunits" |
| Q2 |
Every procedure declares Access explicitly |
Minor |
"Required Patterns · Codeunits" |
| Q3 |
Rec.Modify(false) has inline justification comment |
Major |
"Prohibited" |
| Q4 |
No hardcoded numeric IDs in AL code |
Minor |
"Prohibited" |
| Q5 |
No obsoleted patterns (LookupFormId, RunFormLink) |
Blocker |
"Prohibited" |
| Q6 |
File naming matches <ObjectName>.<ObjectType>.al |
Minor |
"File naming" |
| Q7 |
Indentation is 4 spaces (no tabs) |
Nit |
"Style" |
| Q8 |
Section order inside tables/pages matches contract |
Nit |
"Style" |
Test coverage (2 rules)
| # |
Rule |
Severity |
Source in contract |
| T1 |
Every public codeunit has a matching test codeunit |
Major |
"Test Coverage" |
| T2 |
Each public procedure has at least one test method |
Minor |
"Test Coverage" |
Permissions (3 rules)
| # |
Rule |
Severity |
Source in contract |
| P1 |
Every object declared in the app appears in ≥1 permission set |
Blocker |
"Permissions" |
| P2 |
Permission sets follow naming CEB <Feature> Basic/Full |
Minor |
"Permissions" |
| P3 |
At least one Basic and one Full permission set per feature area |
Minor |
"Permissions" |
Workflow
Follow these steps in order.
Step 1 · Verify contract presence
- Check that
.github/copilot-instructions.md exists
- If missing: emit finding
[Blocker · Compliance] No copilot-instructions.md found — running with reduced rule set
- Parse the contract and extract which rules are declared. Only check rules
that are declared.
Step 2 · Enumerate AL objects
- Read every
*.al file in the declared appFolders from .AL-Go/settings.json
(or app/ by default)
- For each file, extract object type, ID, name, declared properties, fields,
procedures
Step 3 · Apply the rule catalogue
- For every object, run the rules in the catalogue above
- Record each violation as a finding with these fields:
id (e.g. C3, Q1)
severity (Blocker, Major, Minor, Nit)
class (Compliance, Code quality, Test coverage, Permissions)
message (short human-readable description)
file (relative path)
line (starting line number)
remediation (one-sentence suggestion · never code)
contract_source (which section of the contract backs this rule)
Step 4 · Aggregate and prioritize
- Group findings by class
- Within each class, sort by severity (Blocker → Major → Minor → Nit)
- Within severity, sort by file path then line number
Step 5 · Emit the report
Use the output format below. Stick to it exactly.
Output format
# skill-diagnostics · audit report
**Scanned:** <N> files · <M> objects
**Contract:** `.github/copilot-instructions.md` (<rules_declared>/<rules_catalogue> rules active)
## Summary
- **Blocker:** <n1>
- **Major:** <n2>
- **Minor:** <n3>
- **Nit:** <n4>
## Findings
### Compliance (<count>)
- **[C3 · Blocker]** Table `CEB Sample Table` missing `DataClassification`
at object level
- `app/src/Tables/CEBSampleTable.Table.al:7`
- *Remediation*: add `DataClassification = CustomerContent;` at object level
- *Rule source*: `copilot-instructions.md` → "Required Patterns · Tables"
### Code quality (<count>)
- ...
### Test coverage (<count>)
- ...
### Permissions (<count>)
- ...
## Skills Applied
| Rule IDs checked | Count | Source |
|---|---|---|
| C1, C2, C3, C4, C5, C6, C7 | 7 | copilot-instructions.md → "Required Patterns · Tables / Pages / Enums" |
| Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8 | 8 | copilot-instructions.md → "Required Patterns · Codeunits" + "Prohibited" + "Style" |
| T1, T2 | 2 | copilot-instructions.md → "Test Coverage" |
| P1, P2, P3 | 3 | copilot-instructions.md → "Permissions" |
Rules skipped because not declared in contract: <list or "none">
Constraints
- NEVER modifies code. This skill only reports. If the user asks for
automatic fixes, politely decline and point them to
skill-fix (if
available) or manual remediation.
- NEVER invents rules. If a rule sounds reasonable but is not declared
in the contract, do not apply it. Instead, list it in a separate section
called "Suggested contract additions" at the end of the report.
- NEVER aggregates severities into a single "score". Findings are
qualitative · a single Blocker matters more than ten Nits.
- Report is idempotent. Running the skill twice on the same workspace
produces the same output.
- Findings cite file:line. Every finding must be traceable to a specific
location in the source.
References
Example invocations
Any of these trigger this skill via Copilot's auto-match on the description:
- "Audit my workspace for compliance issues"
- "Run a diagnostics scan before I open the PR"
- "Check which objects violate the project contract"
- "Give me a list of Blocker findings in this repo"
- "Scan for missing tooltips in the tables"
Explicit invocation also works:
Load skill-diagnostics and scan the workspace. Use the output format strictly
and include the Skills Applied block at the end.
1---2name: skill-diagnostics3description: Perform a static audit of an AL workspace for Business Central against the project's copilot-instructions.md contract. Reports findings by class (Compliance, Code quality, Test coverage, Permissions) and severity (Blocker, Major, Minor, Nit) with file:line citations. Never modifies code. Never invents rules. Use when asked to audit a workspace, run a compliance check, review before PR, or diagnose contract drift.4license: CC-BY-4.05---67# skill-diagnostics89## Purpose1011Perform a **static audit** of an AL workspace against the project's12`copilot-instructions.md` contract. Produce a structured report of findings.13**Report only.** Never modify source code. Never invent rules that are not14declared in the contract.1516## When to load1718Load this skill when the user asks you to:1920- Audit the workspace / run a compliance check / scan for issues21- Review the code before a PR / before a release22- Diagnose why a new file does not match project conventions23- List all violations of the `copilot-instructions.md` contract24- Generate a contract-drift report2526## Input expectations2728- Repository contains `.github/copilot-instructions.md` (required · if missing,29 emit a Blocker finding and continue with a reduced rule set)30- Workspace contains one or more AL projects with `app.json`31- Optional: test folder(s) declared in AL-Go `settings.json` under `testFolders`3233## Finding classes3435Group every finding into exactly **one** of four classes:3637| Class | What it covers |38|---|---|39| **Compliance** | Object prefix, ID range, DataClassification, Caption/ToolTip presence |40| **Code quality** | XML docs, explicit `Access`, prohibited patterns, style ordering |41| **Test coverage** | Missing test codeunits, public procedures without tests |42| **Permissions** | Objects missing from permission sets |4344## Severity scale4546| Severity | Meaning | Rule of thumb |47|---|---|---|48| **Blocker** | Breaks contract at a fundamental level · must fix before merge | Missing DataClassification, ID out of range, no permission set entry |49| **Major** | Violates a required pattern declared in the contract | Missing Caption/ToolTip, public procedure without XML doc |50| **Minor** | Style deviation or soft convention | Wrong section order, hardcoded numeric ID in code |51| **Nit** | Noise-level observation · safe to ignore | Inconsistent indentation within a file |5253**If in doubt between two levels, downgrade.** A noisy Blocker-heavy report54erodes trust. Reserve Blocker for things that would fail review hard.5556## Rule catalogue · the ~20 rules this skill checks5758Rules map 1:1 to statements in `copilot-instructions.md`. If a rule is not59declared in the contract, **do not check it**.6061### Compliance (7 rules)6263| # | Rule | Severity | Source in contract |64|---|---|---|---|65| C1 | Every new object name starts with the declared prefix | Major | "Object prefix" |66| C2 | Object IDs fall inside the declared `idRanges` of `app.json` | Blocker | "ID Range" |67| C3 | Every table has `DataClassification` at object level | Blocker | "Required Patterns · Tables" |68| C4 | Every table field has `Caption` | Major | "Required Patterns · Tables" |69| C5 | Every table field has `ToolTip` (except PK of lookup tables) | Major | "Required Patterns · Tables" |70| C6 | Every page has `ApplicationArea` and `UsageCategory` | Major | "Required Patterns · Pages" |71| C7 | Every enum declares `Extensible = true;` unless exception documented | Minor | "Required Patterns · Enums" |7273### Code quality (8 rules)7475| # | Rule | Severity | Source in contract |76|---|---|---|---|77| Q1 | Public procedures have XML documentation (`///`) | Major | "Required Patterns · Codeunits" |78| Q2 | Every procedure declares `Access` explicitly | Minor | "Required Patterns · Codeunits" |79| Q3 | `Rec.Modify(false)` has inline justification comment | Major | "Prohibited" |80| Q4 | No hardcoded numeric IDs in AL code | Minor | "Prohibited" |81| Q5 | No obsoleted patterns (`LookupFormId`, `RunFormLink`) | Blocker | "Prohibited" |82| Q6 | File naming matches `<ObjectName>.<ObjectType>.al` | Minor | "File naming" |83| Q7 | Indentation is 4 spaces (no tabs) | Nit | "Style" |84| Q8 | Section order inside tables/pages matches contract | Nit | "Style" |8586### Test coverage (2 rules)8788| # | Rule | Severity | Source in contract |89|---|---|---|---|90| T1 | Every public codeunit has a matching test codeunit | Major | "Test Coverage" |91| T2 | Each public procedure has at least one test method | Minor | "Test Coverage" |9293### Permissions (3 rules)9495| # | Rule | Severity | Source in contract |96|---|---|---|---|97| P1 | Every object declared in the app appears in ≥1 permission set | Blocker | "Permissions" |98| P2 | Permission sets follow naming `CEB <Feature> Basic/Full` | Minor | "Permissions" |99| P3 | At least one `Basic` and one `Full` permission set per feature area | Minor | "Permissions" |100101## Workflow102103Follow these steps in order.104105### Step 1 · Verify contract presence106107- Check that `.github/copilot-instructions.md` exists108- If missing: emit finding `[Blocker · Compliance] No copilot-instructions.md109 found — running with reduced rule set`110- Parse the contract and extract which rules are declared. **Only check rules111 that are declared.**112113### Step 2 · Enumerate AL objects114115- Read every `*.al` file in the declared `appFolders` from `.AL-Go/settings.json`116 (or `app/` by default)117- For each file, extract object type, ID, name, declared properties, fields,118 procedures119120### Step 3 · Apply the rule catalogue121122- For every object, run the rules in the catalogue above123- Record each violation as a **finding** with these fields:124 - `id` (e.g. `C3`, `Q1`)125 - `severity` (Blocker, Major, Minor, Nit)126 - `class` (Compliance, Code quality, Test coverage, Permissions)127 - `message` (short human-readable description)128 - `file` (relative path)129 - `line` (starting line number)130 - `remediation` (one-sentence suggestion · never code)131 - `contract_source` (which section of the contract backs this rule)132133### Step 4 · Aggregate and prioritize134135- Group findings by class136- Within each class, sort by severity (Blocker → Major → Minor → Nit)137- Within severity, sort by file path then line number138139### Step 5 · Emit the report140141Use the output format below. Stick to it exactly.142143## Output format144145```markdown146# skill-diagnostics · audit report147148**Scanned:** <N> files · <M> objects149**Contract:** `.github/copilot-instructions.md` (<rules_declared>/<rules_catalogue> rules active)150151## Summary152153- **Blocker:** <n1>154- **Major:** <n2>155- **Minor:** <n3>156- **Nit:** <n4>157158## Findings159160### Compliance (<count>)161162- **[C3 · Blocker]** Table `CEB Sample Table` missing `DataClassification`163 at object level164 - `app/src/Tables/CEBSampleTable.Table.al:7`165 - *Remediation*: add `DataClassification = CustomerContent;` at object level166 - *Rule source*: `copilot-instructions.md` → "Required Patterns · Tables"167168### Code quality (<count>)169170- ...171172### Test coverage (<count>)173174- ...175176### Permissions (<count>)177178- ...179180## Skills Applied181182| Rule IDs checked | Count | Source |183|---|---|---|184| C1, C2, C3, C4, C5, C6, C7 | 7 | copilot-instructions.md → "Required Patterns · Tables / Pages / Enums" |185| Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8 | 8 | copilot-instructions.md → "Required Patterns · Codeunits" + "Prohibited" + "Style" |186| T1, T2 | 2 | copilot-instructions.md → "Test Coverage" |187| P1, P2, P3 | 3 | copilot-instructions.md → "Permissions" |188189Rules skipped because not declared in contract: <list or "none">190```191192## Constraints193194- **NEVER modifies code.** This skill only reports. If the user asks for195 automatic fixes, politely decline and point them to `skill-fix` (if196 available) or manual remediation.197- **NEVER invents rules.** If a rule sounds reasonable but is not declared198 in the contract, do not apply it. Instead, list it in a separate section199 called "Suggested contract additions" at the end of the report.200- **NEVER aggregates severities into a single "score".** Findings are201 qualitative · a single Blocker matters more than ten Nits.202- **Report is idempotent.** Running the skill twice on the same workspace203 produces the same output.204- **Findings cite file:line.** Every finding must be traceable to a specific205 location in the source.206207## References208209- Agent Skills specification: https://agentskills.io/specification210- Workshop Bloque 02 material: https://javiarmesto.github.io/workshop-v-valley-aldc-2026-04/bloques/02-aldc/211- Project contract: `.github/copilot-instructions.md` (sibling file)212213## Example invocations214215Any of these trigger this skill via Copilot's auto-match on the description:216217- "Audit my workspace for compliance issues"218- "Run a diagnostics scan before I open the PR"219- "Check which objects violate the project contract"220- "Give me a list of Blocker findings in this repo"221- "Scan for missing tooltips in the tables"222223Explicit invocation also works:224225```226Load skill-diagnostics and scan the workspace. Use the output format strictly227and include the Skills Applied block at the end.228```