Close AL development contract gaps

Bound post-implementation review rounds, expose output kinds in Entry
dispatch, enforce capability coverage, map BCFIX-HANDOFF v1, clarify
no-knowledge behavior, and reject repository-escaping skill paths.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 638b66d2-9f06-4f60-8781-808709e1485c
This commit is contained in:
Jesper Schulz-Wedde 2026-09-04 13:36:49 +02:00
parent 56b80e6dcf
commit f6fca1d56d
15 changed files with 356 additions and 52 deletions

View file

@ -9,6 +9,11 @@ This is BCQuality's host-native adapter for standalone plugin installations. It
When the target repository exposes a more specific local workflow for the request, such as an end-to-end bug-fix skill with its own environment and delivery gates, prefer that repository workflow unless the caller explicitly asks to use BCQuality's generic development skill.
This adapter is deliberately knowledge-backed: if BCQuality has no applicable
guidance, it returns a visible `no-knowledge` result without changing code. Use
the repository's normal coding workflow for unbacked requests, or add the
missing BC-specific knowledge before expecting this skill to implement them.
## Execute
1. Resolve `PLUGIN_ROOT` to the directory containing this plugin's root `plugin.json`. This file is `PLUGIN_ROOT/skills/al-development/SKILL.md`; when the host does not expose the plugin root, resolve it two levels above this file.

View file

@ -66,7 +66,7 @@ application-area: [all]
`sub-skills` is an optional field. When present and non-empty, the skill is a **super-skill** that composes other action skills; see *Composition* below. Values are repo-relative paths to action-skill files.
`quality-skill` is optional on an action skill that emits an `implementation-report`. It names one repo-relative review action skill to run over the completed diff. It is a post-implementation gate, not a composed sub-skill: Entry does not route through it, and its complete findings-report is returned in `review`. Consumer configuration still applies; if the named quality skill is disabled or unavailable, record its validation as `not-run` and do not claim `completed`.
`quality-skill` is optional on an action skill that emits an `implementation-report`. It names one repo-relative review action skill to run over the completed diff. It is a post-implementation gate, not a composed sub-skill: Entry does not route through it, and its final complete findings-report is returned in `review`. `quality-round-limit` is the required positive maximum number of review/fix rounds when a quality skill is declared. Consumer configuration still applies; if the named quality skill is disabled or unavailable, record its validation as `not-run` and do not claim `completed`.
`guidance-skill` is optional on an action skill that emits an `implementation-report`. It names one repo-relative read-only action skill that accepts a `development-plan` and emits a `development-guidance-report`. The implementation skill invokes it after forming its plan and before editing product code. Consumer configuration still applies; when guidance is disabled or unavailable, the implementation skill must not claim knowledge-backed development.
@ -346,6 +346,13 @@ An action skill with `outputs: [implementation-report]` emits one JSON document:
}
],
"review": { "...full findings-report from the post-implementation review..." : null },
"review-rounds": [
{
"round": 1,
"outcome": "clean | fixing | stalled | limit-reached",
"gating-finding-ids": ["string"]
}
],
"suppressed": [
{
"reference": { "path": "string", "sha": "string" },
@ -378,6 +385,8 @@ An action skill with `outputs: [implementation-report]` emits one JSON document:
**`review`** is optional for generic implementation skills and required when a skill's instructions mandate post-implementation review. When present, it is the complete findings-report returned by that review skill, not a rewritten summary.
**`review-rounds`** records every quality-skill invocation in order. `gating-finding-ids` contains the `blocker` and `major` IDs from that round. `clean` ends successfully; `fixing` means the skill applied justified fixes before another round; `stalled` means the same gating set persisted or no safe progress was possible; `limit-reached` means the configured round cap was exhausted. The array length MUST NOT exceed `quality-round-limit`. `stalled` or `limit-reached` requires implementation outcome `partial`, the final findings-report in `review`, and every unresolved gating item in `remaining`.
**`suppressed`** has the same semantics as in a findings-report and records applicable knowledge excluded by layer precedence or configuration.
**`remaining`** contains concrete unfinished work only. It is empty for `completed`.

View file

@ -99,7 +99,8 @@ Emit a single JSON document conforming to the output contract below. Entry does
"path": "microsoft/skills/review/al-code-review.md"
},
"rationale": "string",
"inputs": ["pr-diff"]
"inputs": ["pr-diff"],
"outputs": ["findings-report"]
}
],
"skipped": [
@ -126,6 +127,7 @@ Emit a single JSON document conforming to the output contract below. Entry does
- `skill.version` — copied from the dispatched skill's frontmatter so the orchestrator can detect drift between dispatch time and execution.
- `rationale` — short human-readable string, for logs and traceability.
- `inputs` — the intersection of `task-context.inputs-available` and the skill's declared `inputs`. The agent MUST pass exactly this subset when invoking the skill. Sending a strict intersection avoids accidental information leakage between skills.
- `outputs` — the dispatched skill's complete, single-element `outputs` value copied from frontmatter. This lets an orchestrator distinguish read-only `findings-report` and `development-guidance-report` work from repository-changing `implementation-report` work before invoking the skill. An orchestrator MAY require an additional write confirmation for `implementation-report`; it MUST NOT infer side effects from the skill ID or title.
Ordering of `dispatch[]` is not significant.
@ -163,7 +165,8 @@ Populated example (PR review on a repo where only `al-performance-review` is ena
{
"skill": { "id": "al-performance-review", "version": 1, "path": "microsoft/skills/review/al-performance-review.md" },
"rationale": "Goal 'review pull request' matched; inputs-available contains pr-diff.",
"inputs": ["pr-diff"]
"inputs": ["pr-diff"],
"outputs": ["findings-report"]
}
],
"skipped": [
@ -177,7 +180,7 @@ Populated example (PR review on a repo where only `al-performance-review` is ena
1. Invoke Entry with the orchestrator-supplied task context.
2. Receive the dispatch record.
3. For each entry in `dispatch[]`, read the referenced action skill, execute its Source → Relevance → Worklist → Action steps per DO, and produce the report kind declared by that skill's single `outputs` value.
3. For each entry in `dispatch[]`, inspect `outputs` before invocation, read the referenced action skill, execute its Source → Relevance → Worklist → Action steps per DO, and produce the declared report kind. Verify the file's frontmatter output still equals the dispatch value; return `failed` on drift rather than executing an unexpectedly mutating skill.
4. Return the action-skill reports to the orchestrator. When Entry's `outcome` is `no-match` or `failed`, return the dispatch record itself so the orchestrator can log the reason.
READ and DO are the contracts that govern what the dispatched skills do. An agent that has not yet read READ and DO reads them when it executes the first dispatched skill — they are not prerequisites for invoking Entry.