Normalize SCM knowledge and review ownership

Align article and AL sample conventions, keep BC facts separate from review mechanics, and clarify reciprocal Finance ownership without bespoke shared test assertions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-09-17 18:59:22 +02:00
parent 9ac62e3967
commit 525e84e183
30 changed files with 148 additions and 362 deletions

View file

@ -15,77 +15,57 @@ application-area: [all]
# AL Supply Chain Management review
Reviews AL source against the `scm` knowledge domain. This leaf invokes no
sub-skills and is composed by `al-code-review`. It accepts diffs, individual
files, and complete app folders; for a folder, inspect every relevant AL file,
not a representative sample. A folder supplies no historical baseline.
sub-skills and is composed by `al-code-review`. For a folder, inspect every
relevant AL file; a folder supplies no historical baseline.
## Source
Apply the source-surface gate in Relevance before retrieving knowledge. If the
gate passes, use READ's **Bounded retrieval for review skills** workflow with
`-Domain scm` and `-Technologies @('al')`. Consume every catalog page across
enabled layers, preserving exact paths, complete keywords, applicability, and
unknown dimensions. Select articles using catalog metadata only; never use an
index row as the basis for a finding.
Entry owns index preparation. Do not rebuild the index in this leaf. When a
helper or prepared index is unavailable or invalid, follow READ's explicit
path-discovery and bounded native-read fallback through EOF. A retrieval
failure is not an empty or clean review.
Apply Relevance's source gate before retrieval. For a relevant scope, use READ's
**Bounded retrieval for review skills** with `-Domain scm` and
`-Technologies @('al')`. Consume every catalog page across enabled layers,
preserving exact paths and applicability. Select from metadata, then read only
worklisted complete articles. Entry owns index preparation; the leaf does not
rebuild. Unavailable/invalid helpers or indexes use READ's bounded native-read
fallback, never a success-shaped empty result.
## Relevance
First inspect the supplied scope for an SCM source surface: a changed
procedure, trigger, subscriber, or bound action that writes or posts inventory,
cost, application, reservation, tracking, warehouse, transfer, or planning
state, or calculates availability for a supply/demand decision. Resolve record
and codeunit declarations, source tables, event publishers, and nearby calls
within the supplied scope. Do not infer object identity from a variable name.
Resolve changed record/codeunit types, source tables, publishers and calls.
Gate on code that mutates or posts inventory, application, reservation,
tracking, warehouse, transfer or planning state, or makes a supply/demand
availability decision. Stock displays and other read-only queries without
that decision do not pass the gate. Names, comments, captions, an `Item`
reference or a broad `ApplicationArea` alone are not signals.
If no SCM surface remains, return `not-applicable` with zero coverage
and no article-body retrieval; in mixed diffs, retain only relevant procedures
and their visible supporting context.
An `Item` reference, a field caption, an unrelated ledger read, an object name
containing "warehouse", or a broad `ApplicationArea` alone does not pass this
gate. Comments and display strings are not execution evidence. When no source
surface passes, return `not-applicable` with zero coverage and no article-body
reads. In a mixed diff, worklist only the relevant procedures and their visible
supporting context, not every AL file in the app. Unknown application areas do
not by themselves exclude codeunits or subscribers.
SCM owns `"Item Ledger Entry"`, `"Value Entry"`, `"Capacity Ledger Entry"`,
`"Warehouse Entry"` and inventory posting/application records. Pure `"G/L Entry"`,
`"Cust. Ledger Entry"`, `"Vendor Ledger Entry"`, `"Detailed Cust. Ledg. Entry"`,
`"Detailed Vendor Ledg. Entry"`, `"VAT Entry"` and financial-only posting
mutations belong to Finance. They remain outside SCM even if Finance is absent
or disabled; do not reclaim them as SCM agent findings. Ownership is not a
claim that every owned surface already has a dedicated article.
For candidates, apply READ's frontmatter matching semantics:
- `bc-version`: the target BC major version from application dependency or
host context, not the extension's own version; otherwise unknown.
- `technologies`: AL.
- `countries`: the known target localization or host context; otherwise
unknown, not a guess based on the developer's language.
- `application-area`: the actual known task/object areas, not a substituted
`[all]`. Use explicit inventory, warehousing, assembly, manufacturing, or
supply-chain context to narrow the relevant source, not as proof of a defect.
Discard nonmatching articles. Retain conditionally applicable articles only
when configuration permits; cap their findings at `medium` confidence and
name every unknown dimension in the message.
Apply READ's frontmatter filters using the target BC major version from
application dependency/host context (not the extension version), AL, known
localization and actual task/object application areas. Omitted context stays
unknown, not `[all]`; unknown areas alone do not exclude codeunits/subscribers.
Retain conditional articles only when configured, cap their findings at
`medium`, and name every unknown dimension.
## Worklist
Extract deterministic tokens from the gated source: resolved object/type
names, quoted field names, methods, enum members, and called publishers.
Lowercase invariantly, replace punctuation and whitespace runs with one hyphen,
and trim leading/trailing hyphens. Thus `"Item Ledger Entry"` becomes
`item-ledger-entry`, `"Qty. (Base)"` becomes `qty-base`, and `RunWithCheck`
becomes `runwithcheck`. Apply the same normalization to catalog keywords.
Match whole normalized tokens/phrases, not substrings such as `item` in an
unrelated identifier. Do not manufacture synonyms that are not supported by
the changed source or the targeted cues.
Extract resolved object/type names, quoted fields, methods, enum members and
publishers. Normalize these and catalog keywords by lowercasing invariantly,
replacing punctuation/whitespace runs with one hyphen and trimming hyphens:
`"Item Ledger Entry"` becomes `item-ledger-entry`; `RunWithCheck` becomes
`runwithcheck`. Match whole tokens/phrases, not identifier substrings.
Select a catalog row only when a keyword intersects these tokens, or its
path/title/description identifies the same gated source surface **and
operation**. Object declarations establish context; field assignments, calls,
and decision logic establish the operation to evaluate. A shared table name
does not select every rule using that table.
Use these targeted candidate-selection cues, resolving each slug to its
actual enabled catalog paths. They select articles to read, not findings to
emit; all platform reasoning and exceptions remain in those articles.
Select matching keywords or catalog topics only for the same source surface
**and operation**. The following cues resolve slugs to actual enabled catalog
paths; they select articles, not findings. Facts and exceptions stay in articles.
| Changed source surface and operation | Article slug |
| --- | --- |
@ -99,115 +79,43 @@ emit; all platform reasoning and exceptions remain in those articles.
| `Inventory`, `CalcQtyAvailableToPromise`, or stock sums used in a dated supply/demand promise, including changed location/variant/date filters and source-demand context | `use-date-aware-availability-for-promising` |
| `"Requisition Line"` action-message execution, accepted planning suggestions, `"Req. Wksh.-Make Order"`, `CarryOutBatchAction`, or linked supply creation/change plus requisition-line deletion | `carry-out-requisition-actions-through-the-standard-workflow` |
Do not select a cue solely from a caption, comment, or unrelated declaration.
Use the same gates for clean supported calls so their article exclusions are
evaluated, not just suspicious writes. Applicability is never an anti-pattern.
Resolve normative conflicts per READ after reading the selected complete
articles. Keep enabled-layer candidates additive unless guidance actually
contradicts; do not deduplicate merely by filename. Record losing candidates
in `suppressed` with `layer-precedence`, and configuration-hidden candidates
with `configuration`. Noncandidates are not suppressions.
Order exact worklisted paths ordinally and retrieve complete bodies in stable
chunks of at most eight, following every continuation within each chunk.
Never turn the chunk size into a top-eight cutoff. Read samples only when
needed, via their exact READ links and bounded sample retrieval.
Route clean supported calls through the same cues, not just suspicious writes.
Resolve actual normative conflicts per READ, preserving additive layers and
recording `layer-precedence`/`configuration` suppressions, not noncandidates.
Retrieve exact paths in ordinal chunks of at most eight, consume every
continuation, and never impose a top-eight cutoff. Samples use exact READ links.
## Action
Evaluate the visible source against each opened article's normative Best
Practice and Anti Pattern, including its scope and exclusions. Establish the
record's persistence, caller contract, document type/state, and affected
operation from evidence before reporting. Consult the article for treatment
of temporary buffers, supported publisher parameters, managed posting paths,
and legitimate read-only calculations; the skill itself defines no BC rule.
Do not infer missing work in an unseen caller or report every use of a routed
API. A supported alternative is not a defect.
Evaluate every opened article's normative facts, scope and exclusions against
visible persistence, caller contract, document state and operation. Emit only
concrete violations with business consequences and supported remediation; a
declaration, valid alternative or unseen caller is not evidence of a defect.
Emit only a concrete violation with its business consequence and supported
remediation. Use `major` for a demonstrated material SCM defect, `minor` for
a narrower best-practice conflict, and `blocker` only if the opened article
establishes a violated platform-level guarantee. Relevance alone produces no
finding. Deduplicate overlapping findings that prescribe the same correction;
prefer the article that owns the specific operation and retain any other
applicable article as a supporting reference.
- Use `major` for material SCM defects, `minor` for narrower best-practice
conflicts, and `blocker` only for an article-established platform guarantee.
Applicability alone produces no finding. High confidence requires unambiguous
evidence and known applicability; inference/conditional applicability caps it
at `medium`.
- Apply DO's single-owner deduplication. Equivalent findings for the same
inventory-originated posting bypass and correction have one SCM primary
owner, even when financial records are downstream. Prefer the most specific
SCM article and retain other applicable references as supporting evidence.
Distinct independent financial defects remain Finance; do not duplicate them.
- Agent findings stay strictly SCM-scoped under DO's precision bar, with
`references: []`, an `agent:` id and `minor`/`medium` ceilings. Generic AL and
other domains' concerns remain outside this leaf.
- Supply literal `suggested-code` only for a complete, local, unambiguous fix,
not a sample call that omits workflow setup/source identity. Explain omitted
mechanical-looking fixes with `suggested-code-omission-reason`.
Copy `findings[].id` verbatim from the primary article's exact catalog path;
it must equal `references[0].path`. Cite only complete articles actually read.
Use `high` confidence only for unambiguous source evidence with known
applicability, `medium` for justified inference or conditional applicability.
Never label a guessed API signature or missing workflow context high confidence.
Agent findings are optional and strictly SCM-scoped. Follow DO's precision
bar: concrete, material defects only, with `references: []`, an `agent:` id,
severity at most `minor`, and confidence at most `medium`. Omit generic AL,
style, performance, privacy, and unrelated technical findings owned by other
leaves. Do not invent a finding to compensate for an empty worklist.
For an unambiguous local fix, supply literal replacement AL in
`suggested-code`, with a location range covering exactly those lines. Do not
replace an entire business workflow with a sample call that omits the
caller's setup, filters, source identity, or validations. When a mechanical-
looking fix cannot be expressed safely, give `suggested-code-omission-reason`.
Outcomes follow DO: `completed` after evaluating the complete worklist,
including a clean result; `not-applicable` when the source gate fails;
`no-knowledge` when no applicable corpus survives filtering/configuration;
`partial` when only part of the worklist was evaluated; `failed` when no
reliable result can be produced. A source match with no matching article is
`completed` with an empty worklist, not a claimed evaluation of every SCM
concern. Explain partial/failed results and report accurate coverage.
Outcome selection follows DO, including accurate coverage and reasons for
`partial`/`failed`. No surviving applicable corpus is `no-knowledge`; an existing
corpus with no matching operation is `completed` with an empty worklist.
## Output
Return one strict JSON findings-report per DO and
`schemas/findings-report.schema.json`, with no surrounding prose. Every
finding, including an agent finding, must have
`domain: "Supply Chain Management"`. Do not set `from-sub-skill` in a leaf
report; the coordinator adds it. All locations must identify existing lines
in the supplied source, and any range must start at `location.line`.
A knowledge-backed finding with an exact article id:
```json
{
"skill": { "id": "al-scm-review", "version": 1 },
"outcome": "completed",
"summary": {
"counts": { "blocker": 0, "major": 1, "minor": 0, "info": 0 },
"coverage": { "worklist-size": 1, "items-evaluated": 1 }
},
"findings": [
{
"id": "microsoft/knowledge/scm/cancel-reservations-through-reservation-management.md",
"severity": "major",
"message": "This cancellation deletes only the negative reservation row. Use Reservation Engine Mgt. cancellation so counterpart and surviving tracking are handled by the owning workflow.",
"location": { "file": "src/CancelReservation.Codeunit.al", "line": 16 },
"references": [
{ "path": "microsoft/knowledge/scm/cancel-reservations-through-reservation-management.md" }
],
"confidence": "high",
"domain": "Supply Chain Management",
"suggested-code-omission-reason": "The replacement also requires a codeunit declaration outside the reported line."
}
],
"suppressed": []
}
```
An unrelated AL change, excluded before article retrieval:
```json
{
"skill": { "id": "al-scm-review", "version": 1 },
"outcome": "not-applicable",
"outcome-reason": "The supplied AL changes contain no SCM posting, state mutation, or supply/demand availability surface.",
"summary": {
"counts": { "blocker": 0, "major": 0, "minor": 0, "info": 0 },
"coverage": { "worklist-size": 0, "items-evaluated": 0 }
},
"findings": [],
"suppressed": []
}
```
Output conforms to the DO findings-report contract and shared schema. Every
finding MUST set `domain` to `"Supply Chain Management"`. Knowledge-backed ids
equal the primary opened article's exact catalog path. The coordinator, not
this leaf, sets `from-sub-skill`.