bcquality/custom/skills/review/cmfrt-standards-review.md
BeytullahCengiz88 afb1fa2883 Add CMFRT naming conventions, object ID ranges, and patterns documentation
- Introduced guidelines for using the "CMFRT" prefix in object names, fields, and procedures to avoid naming collisions and ensure clarity.
- Established rules for object ID ranges to prevent conflicts with other extensions and maintain historical integrity.
- Documented best practices and anti-patterns for various coding patterns, including case statements, interface injection, label usage, and validation methods.
- Implemented a standards review skill to evaluate AL source changes against CMFRT company standards, ensuring compliance with naming, permissions, and architectural patterns.
2026-07-14 14:09:04 +02:00

8.1 KiB

kind id version title description inputs outputs bc-version technologies countries application-area
action-skill cmfrt-standards-review 1 CMFRT AL standards review Reviews AL source changes for CMFRT company standards — naming, object IDs, permission sets, breaking-changes, events, patterns, and architecture.
pr-diff
file-path
findings-report
all
al
w1
all

CMFRT AL standards review

Reviews AL source changes against the CMFRT company standards defined in custom/knowledge/. This is a leaf action skill: it invokes no sub-skills. It is dispatched alongside microsoft/skills/review/al-code-review.md for every CMFRT project review.

An orchestrator invokes this skill with either a pr-diff (the standard PR-review entry point) or a file-path (single-file review). The skill produces a single JSON document conforming to the DO output contract.

Source

Read the BCQuality knowledge index once (knowledge-index.json at the checkout root). Take every entry whose layer is custom as the candidate set — this covers all domains under custom/knowledge/: naming, security, breaking-changes, events, patterns, and architecture. Do not open individual article files at this step.

Relevance

Apply frontmatter matching rules defined in READ against the task context:

  • bc-version — from the target branch's app.json or orchestrator context; unknown if absent.
  • technologies[al].
  • countries — from app.json or orchestrator context; default unknown.
  • application-area — union of application areas declared by changed objects; unknown if not determinable.

Discard candidates whose filter dimensions explicitly do not match. Retain conditionally applicable candidates (any dimension unknown); findings from those files MUST have confidence no higher than medium and the message MUST name the unknown dimension.

Worklist

Narrow the relevant candidates to those that apply to the changes under review. Compute overlap against:

  • Changed AL object names, types, and IDs — weighted toward tables, table extensions, codeunits, interfaces, permission sets, and any object whose ID, name, or prefix is being set or changed. Match against the naming and architecture domain candidates.
  • Changed procedure signatures and parameter lists — especially global procedures being added, renamed, or extended. Match against breaking-changes and events candidates.
  • Changed permission set objects and their IncludedPermissionSets chains. Match against security candidates.
  • Tokens extracted from the diff: ObsoleteState, ObsoleteReason, ObsoleteTag, Confirm, case, else, interface, implements, IntegrationEvent, OnBefore, OnAfter, Handled, IsHandled, IncludedPermissionSets, Assignable, procedure, local procedure, Validate, Init, Insert, OnInsertRecord, Buffer, Caption, ToolTip, Label, Comment, CopyStr, MaxStrLen, TryFunction, Codeunit.Run, field(, value(.
  • Field-assignment shape: contiguous runs of Record.Field := Value statements on a non-buffer record variable inside a creator/method codeunit. Match against the patterns candidate cmfrt-validate-not-assign.
  • API page triggers: PageType = API combined with SourceTable on a base application table, or an OnInsertRecord body containing Rec.Insert or exit(false). Match against the architecture candidate cmfrt-buffer-table-api-pattern.

A candidate enters the worklist when its keywords intersect the extracted tokens, or when its topic (from the index path, title, and description) matches the type of change in the diff. Read an article's full body only after it enters the worklist.

Resolve layer-precedence conflicts per READ. Since all candidates are in the custom layer, no cross-layer conflict arises unless a microsoft or community file shares a concern; in that case the custom file takes precedence and the lower-precedence file is recorded in suppressed with reason: "layer-precedence".

When no custom knowledge survives filtering, emit outcome: "no-knowledge". When the worklist is empty because no candidates matched the diff, emit outcome: "completed" with an empty findings array.

Action

For each worklist entry, evaluate the diff against its ## Best Practice and ## Anti Pattern sections. Emit findings as follows:

  • Clear Anti Pattern match: severity major or blocker. Use blocker only when the knowledge file explicitly states the pattern violates a platform-level guarantee. Otherwise major.
  • Code that contradicts a Best Practice without being a full anti-pattern: severity minor.
  • File is clearly applicable but no violation is detectable: severity info citing the file.

Set confidence to high for unambiguous token or structural matches, medium for heuristic matches or when any frontmatter dimension was unknown, and low for advisory-only applicability.

Emit findings[].suggested-code whenever the fix is small, local, and mechanical — for example: adding an else clause to a bare case, replacing a Confirm( call with ConfirmManagement.GetResponseOrDefault(, adding ObsoleteState = Pending to a deleted member, correcting a naming or caption prefix, rewriting Record.Field := Value as Record.Validate(Field, Value) (except primary-key/document-no. fields and buffer tables), or replacing a literal CopyStr length with MaxStrLen(Target.Field). The payload must be a literal replacement for the lines in location with no diff markers or commentary. If the fix is mechanical-looking but spans non-contiguous lines or requires context not visible in the diff, set suggested-code-omission-reason instead.

After evaluating all worklist entries, consider whether the diff exhibits a CMFRT standards violation the agent recognises from general AL knowledge that no custom knowledge file covers. Hold such candidates to the precision bar in skills/do.md (Agent findings): emit only concrete, material violations a CMFRT reviewer would agree are wrong. Encode as agent findings with references: [], id prefixed agent:, confidence capped at medium, severity capped at minor.

Outcome selection:

  • completed — every worklist item evaluated, including when findings is empty.
  • no-knowledge — no custom knowledge survived Source, Relevance, and configuration filtering.
  • not-applicable — no AL changes in the diff or technologies filter rejected the task.
  • partial — time or token budget exhausted before worklist completion; set outcome-reason.
  • failed — unrecoverable error; set outcome-reason.

Output

Output conforms to the DO output contract. Example — naming and event violations found:

{
  "skill": { "id": "cmfrt-standards-review", "version": 1 },
  "outcome": "completed",
  "summary": {
    "counts": { "blocker": 0, "major": 1, "minor": 1, "info": 0 },
    "coverage": { "worklist-size": 3, "items-evaluated": 3 }
  },
  "findings": [
    {
      "id": "custom/knowledge/naming/cmfrt-naming-prefix.md",
      "severity": "major",
      "message": "Procedure 'CalculateDiscount' on codeunit 2045710 has no CMFRT prefix. Rename to 'CMFRTBACalculateDiscount' to comply with the CMFRT naming convention.",
      "location": { "file": "src/Sales/Discount.Codeunit.al", "line": 8 },
      "references": [{ "path": "custom/knowledge/naming/cmfrt-naming-prefix.md" }],
      "confidence": "high",
      "suggested-code": "    procedure CMFRTBACalculateDiscount(ItemNo: Code[20]; Qty: Decimal): Decimal"
    },
    {
      "id": "custom/knowledge/events/cmfrt-onbefore-onafter-all-globals.md",
      "severity": "minor",
      "message": "Global procedure 'CMFRTBACalculateDiscount' has no OnBefore/OnAfter integration events. Add both events to allow dependent extensions to intercept or react to this operation.",
      "location": { "file": "src/Sales/Discount.Codeunit.al", "line": 8 },
      "references": [{ "path": "custom/knowledge/events/cmfrt-onbefore-onafter-all-globals.md" }],
      "confidence": "high",
      "suggested-code-omission-reason": "Event declarations span multiple non-contiguous locations in the file."
    }
  ],
  "suppressed": []
}