Commit graph

12 commits

Author SHA1 Message Date
Michael Dieringer
e3d9b8eb25 Fix four merge-critical issues from Jesper's 2026-09-22 review
- al-testing-review.md: the generic ExpectedError cue's asserterror
  Assert.IsTrue/IsFalse exclusion was unconditional, but the
  specialized rule it deferred to only claims the pure-inversion
  shape. A test expecting the guarded Boolean-returning call itself to
  raise fell through both routes. Narrowed the exclusion to the same
  inversion-only condition the specialized cue already uses.
- asserterror-needs-expectederror-and-code.md: the rollback-sentinel
  exception (a trailing asserterror Error(...) used purely to force a
  fixture rollback, not to verify a specific failure) previously lived
  only in skill routing prose. Encoded it directly in the article's
  Anti Pattern section so every consumer of the knowledge base sees it,
  not just this one skill.
- commit-shared-test-fixture-inside-lazy-initialize.good.al/.bad.al:
  replaced hand-rolled Item.Init()/Insert(true) with
  LibraryInventory.CreateItem, so the canonical fixture doesn't itself
  trigger use-library-codeunits-for-test-fixtures.
- table-relation-test-exclude-known-invalid-relations-via-event.good.al/
  .bad.al: declared minimal "Sample Setup"/"Sample Header" tables
  inline instead of referencing undefined symbols, matching this
  repo's own convention that every fixture is self-contained.
2026-09-22 14:35:48 +02:00
Michael Dieringer
69b09db3a6 Fix remaining correctness issues from Jesper's 2026-09-15 re-review
- commit-shared-test-fixture-inside-lazy-initialize: three sub-issues.
  Recommended TestIsolation = Codeunit instead of listing Disabled as an
  equal option - Disabled never rolls back at all ("tests are not
  isolated from each other" per the property's own docs), so a fixture
  this pattern commits under Disabled is permanent database
  contamination unless something else tears it down; Disabled is now
  only mentioned alongside that explicit teardown requirement. Added
  precedence in al-testing-review.md so the deliberate end-of-test
  asserterror Error(...) rollback sentinel isn't also flagged by the
  generic asserterror-needs-expectederror-and-code rule. Rewrote both
  fixtures to actually demonstrate the pattern: persisted fixture data
  (an Item record) instead of an empty comment, a second [Test] method
  that depends on the fixture surviving into it, and an explicit
  Subtype = TestRunner / TestIsolation = Codeunit runner codeunit.

- table-relation-test-exclude-known-invalid-relations-via-event:
  the length/type rule was stated as one global requirement. Verified
  ValidateFieldRelation in codeunit 134926 directly (BCApps reference
  clone) and split it into the two branches the source actually has:
  a field with any unconditional relation needs exact length and exact
  resolved type; a field whose relations are all conditional only fails
  on being shorter (longer is fine) than the largest related field, and
  when the required type is specifically Code, a Text source passes too
  - a tolerance that does not apply on the unconditional side and does
  not extend to a required Text.

Rebased onto upstream/main (one conflict in
transactionmodel-attribute-governs-test-transactions.md - upstream had
already linked its sample references via the READ convention, ours
added a Source section; merged both). Also converted the 3 remaining
plain-backtick sample references in this PR to the READ-convention
markdown-link form, same fix as #156/#157/#158.
2026-09-21 22:49:39 +02:00
Michael Dieringer
1392521a8e Address second round of Jesper Schulz-Wedde's review on PR #159
- commit-shared-test-fixture-inside-lazy-initialize.md: fundamentally
  rewritten. AutoCommit is the documented default TransactionModel, not
  AutoRollback. Explains the real mechanism (Commit() protects a fixture
  from the test method's own later deliberate rollback, per Codeunit.Run/
  TransactionModel-property semantics) and the TestIsolation dependency
  (Disabled/Codeunit survive across methods, Function does not). Fixtures
  rewritten to demonstrate the actual failure/success shape.
- transactionmodel-attribute-governs-test-transactions.md: now states the
  AutoCommit default explicitly and agrees with the article above, closing
  the contradiction Jesper flagged between the two testing articles.
- Deleted confirm-needs-strsubstno-before-confirmhandler-sees-substituted-text
  (.md/.good.al/.bad.al): the underlying platform bug (microsoft/
  ALAppExtensions#23935) was closed as completed in Feb 2024; cannot be
  reproduced or bc-version-pinned on any currently supported version.
- table-relation-test-exclude-known-invalid-relations-via-event.md: added
  the [Scope('OnPrem')] boundary verified against BCApps' Table Relation
  Test codeunit.
- use-assert-isfalse-not-asserterror-for-boolean-checks.md: added a Scope
  section resolving the overlap with asserterror-needs-expectederror-and-code.
- al-testing-review.md: fixed the shared-fixture cue to catch the actual
  anti-pattern instead of the compliant shape, added the missing cue for
  use-assert-isfalse-not-asserterror-for-boolean-checks, wired precedence
  between it and the generic asserterror rule, and removed the cue for the
  deleted article.
- Added in-file Source provenance (specific fluxxus.nl post per article,
  with what was independently verified vs. taken from the post) to the
  three surviving externally-inspired articles, per Jesper's request that
  provenance live in the knowledge file itself, not only the PR description.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:49:17 +02:00
Michael Dieringer
dcd79afc08 Address Jesper Schulz-Wedde's review on PR #159
- transactionmodel-attribute-governs-test-transactions.md: the "Commit
  causes an error" behavior is specific to an explicitly declared
  AutoRollback attribute. A test method with no TransactionModel
  attribute at all is a distinct, valid shape — BCApps' own
  codeunit 134915 "ERM Online Mapping Setup" commits inside a lazy
  Initialize() with no attribute declared, cleaning up via a manual
  asserterror at the end. Evidence for commit-shared-test-fixture-
  inside-lazy-initialize.md (this PR), which is correct as submitted.
- confirm-needs-strsubstno-before-confirmhandler-sees-substituted-text.md:
  reframe as a known, unconfirmed-fix platform defect
  (microsoft/ALAppExtensions#23935) rather than designed behavior; add
  the Message/MessageHandler asymmetry as supporting evidence.
- table-relation-test-exclude-known-invalid-relations-via-event.md:
  note the test-app-only consumer dependency; correct "walks every
  TableRelation field property in the app" to the actual tenant-wide
  Table Relations Metadata scope across installed apps.
- Wire confirm-needs-strsubstno, commit-shared-test-fixture-inside-
  lazy-initialize, and table-relation-test-exclude-known-invalid-
  relations-via-event into al-testing-review.md's candidate-selection
  cues.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 22:48:58 +02:00
Jesper Schulz-Wedde
51597068b1
Add bounded knowledge retrieval (#179)
* Add bounded knowledge retrieval

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0d8b7764-f15a-49ea-8d50-d9147334f8af

* Fix bc-version overflow and pathless-row identity in bounded retrieval

Catalog matching compared an Int32 -BCVersion against a bigint range bound.
PowerShell coerces the right operand to the left operand's type, so a bound
wider than Int32 threw a conversion error and failed the whole domain catalog
rather than the single row. Metadata validation already accepts such bounds,
so compare as bigint on both sides.

The shared pager built its oversized-row message with $row.path, which
throws under Set-StrictMode -Version Latest when a row carries no path,
replacing the explicit bound failure with a property-lookup error. Resolve the
path defensively for dictionary and object rows so the offset-based fallback
is reachable.

Both paths gain regression coverage that fails without these fixes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0d8b7764-f15a-49ea-8d50-d9147334f8af
2026-09-11 12:35:31 +02:00
Jesper Schulz-Wedde
17bb84a25e
Support standalone runners and complete app-folder reviews (#172)
* Document standalone review runner contract

Keep model selection and scheduling outside BCQuality while allowing orchestrators to run isolated review leaves concurrently with deterministic rollup semantics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Support complete app folder reviews

Define folder-path as a current-state review scope and accept it across the standalone adapter, broad coordinator, and every AL review leaf.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Add walk-up app review quick start

Put the complete app-folder installation and prompt flow directly in the README so partners can discover the standalone experience without reading integration details first.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Organize conceptual guides under docs

Move architecture and standalone runner documentation out of the repository root, add a documentation index, and update all inbound links.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-09 16:55:35 +02:00
wenjiefan
c213f1495e Exempt optional notification handlers from the HandlerFunctions execution rule
The narrowed UI-handler guidance still stated the execution rule without the
qualifier the linked Microsoft reference uses. The article said every listed
handler must execute at least once, and the testing leaf skill asked for
`[HandlerFunctions(...)]` to match the invoked handlers exactly. The reference
says every *nonoptional* listed handler must execute, and that send-notification
and recall-notification handlers can be optional. As written, an agent could
flag a deliberately unused optional notification handler.

The discriminator is narrower than the handler type. Both
`[SendNotificationHandler([HandlerIsOptional: Boolean])]` and
`[RecallNotificationHandler([HandlerIsOptional: Boolean])]` take an explicit
optionality argument, so `[SendNotificationHandler(true)]` is exempt while the
same attribute written without the argument stays nonoptional like every other
handler type. Keying the exemption on the argument rather than the type keeps it
checkable from the diff and avoids the opposite false positive, where an agent
stops flagging genuinely nonoptional notification handlers.

Changes:

- The article now states the nonoptional qualifier, explains that optionality is
  declared rather than inferred, and adds an explicit do-not-flag clause. That
  clause also forbids proposing removal, because the listed entry is what keeps
  the test passing on the runs where the notification does fire.
- The testing leaf skill carries the same boundary in its `ui-handlers-in-tests`
  cue, and its mechanical-fix list no longer allows removing a listed optional
  notification handler as a one-click suggestion.
- `SendNotificationHandler` and `RecallNotificationHandler` were missing from the
  skill's testing token list, so notification handlers were not reliably
  surfaced to the relevance step at all. Both are now listed.
- The good sample gains a test that lists an unreached
  `[SendNotificationHandler(true)]`; the bad sample gains the mirror image, an
  unreached `[SendNotificationHandler]` with no optionality argument. The pair
  differs only by that argument, which is the point.
- `evaluation/review-fixtures.json` pins the testing domain to
  `ui-handlers-in-tests` so the boundary is exercised: the good sample is the
  clean control at `minimumCleanRate` 1.0 and the bad sample is the expected
  finding. Keywords were retagged with `notification` and `optional-handler`.

validate_frontmatter.py reports 0 errors; Test-ReviewFixtures.ps1 passes with
32 cases across 16 leaf domains and resolves the testing fixture to this article.
2026-09-02 11:46:13 +02:00
wenjiefan
ead337f9cb Address review guidance feedback
Preserve independent event seams, cover loop-carried handled state, strengthen checkpoint and UI-handler fixtures, and align DeleteAll fallback guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 10646e50-2d8b-4cca-b02b-dfa78629e6a1
2026-08-18 14:09:11 +02:00
wenjiefan
5f1cff2fb6 Refine self-improvement review guidance
Narrow IsHandled, label-scope, UI-handler, checkpoint, and bulk-operation guidance to evidence-backed false-positive boundaries.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-18 11:17:14 +02:00
Jesper Schulz-Wedde
186d8a1314
Complete AL review knowledge readiness (#108)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* Complete AL review knowledge readiness

Fill telemetry and Query coverage, strengthen thin review domains, correct audited content defects, and add deterministic cheap-model evaluation and reference-integrity safeguards.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Generalize review fixture discovery

Derive smoke cases from the leaf, domain, and paired-sample conventions so new leaves require no scoring-contract changes. Keep only exceptional selection/context overrides and fail when retrieval metadata cannot rank the selected article.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Preserve published field IDs in sample

Keep the existing Email and Contact Email field IDs unchanged, clarify that the sample represents an independent baseline, and use a local breaking-change rule for the generic smoke evaluation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Clarify published field identity rules

State explicitly that a published field keeps its ID, name, and type while a replacement is added as a separate field under an unused ID.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

* Align field obsoletion sample baselines

Use Email field ID 3 as the shared baseline so the bad example demonstrates a same-ID rename while the good example retains the original field and adds a separate replacement.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9825b012-e653-496a-9310-c1f4b6f8ac27

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-15 10:55:25 +02:00
Jesper Schulz-Wedde
ae04938c03
Emit human-readable domain label on review findings (#54)
* Emit human-readable domain label on review findings

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>

* Define domain display-label constraints

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

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-15 10:44:50 +02:00
Jesper Schulz-Wedde
98af9aa1fc
Add missing AL review leaf skills (#96)
* Add missing AL review leaves

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 62d512a7-fd54-43dc-8eb5-485b909c72e5

* Refine test isolation review cue

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 62d512a7-fd54-43dc-8eb5-485b909c72e5

---------

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
2026-07-14 12:50:30 +02:00