What changed, and why it matters
This commit reorganizes internal documentation for AI coding assistants. It moves existing developer guidance from one file into separate 'skill' files and adds new style guides for frontend naming and test writing. No application code, configuration, or user-facing behavior was changed.
No security action needed. This is a documentation reorganization with no runtime effect.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors repository agent instructions. AGENTS.md is shortened to point to new .agents/skills/ Markdown files covering Entity Framework migrations, changelog updates, BEM CSS conventions, and Playwright test patterns. A symbolic link .claude -> .agents is added. No source code, build scripts, dependencies, permissions, or runtime logic are modified.
Changed components
Repository documentation only: AGENTS.md, .agents/skills/*, .claude symlinkInspect captured patch +158 / −45
diff --git a/.agents/skills/bem-conventions/SKILL.md b/.agents/skills/bem-conventions/SKILL.md
new file mode 100644
index 0000000..43fa5e3
--- /dev/null
+++ b/.agents/skills/bem-conventions/SKILL.md
@@ -0,0 +1,56 @@
+---
+name: bem-conventions
+description: Use when editing Razor views, view components, CSS, JavaScript DOM selectors, or Playwright tests that depend on frontend selectors. Prefer BEM class selectors over ids for reusable UI hooks.
+---
+
+# BEM Conventions
+
+Use BEM-style class names for frontend selector hooks in Razor views, view components, CSS, JavaScript, and Playwright tests.
+
+## Default Rule
+
+- Prefer class selectors using BEM naming: `.block`, `.block__element`, `.block--modifier`, `.block__element--modifier`.
+- Use these classes for styling hooks, JavaScript DOM queries, and Playwright selectors.
+- Avoid adding or depending on ids for reusable component interaction unless the id is required by platform behavior.
+
+## When Ids Are Acceptable
+
+Keep ids when they are needed for:
+
+- `label for="..."` and control association.
+- Bootstrap or browser wiring such as `aria-labelledby`, `data-bs-target`, modal ids, or datalist `list` targets.
+- ASP.NET model binding compatibility where existing `id` or `name` values are relied on.
+- Legacy compatibility when removing the id would break existing public behavior.
+
+Even when an id must remain, add a BEM class and use the class in new CSS, JavaScript, and tests.
+
+## View Components
+
+For reusable components, use the component name as the BEM block:
+
+```html
+<div class="date-range-selector">
+ <button class="date-range-selector__toggle">This month</button>
+ <input class="date-range-selector__timezone" />
+</div>
+```
+
+Examples:
+
+- `SearchStringInput` -> `.search-string-input__text`, `.search-string-input__term`
+- `DateRangeSelector` -> `.date-range-selector__toggle`, `.date-range-selector__preset`
+- `ClearAllFilters` -> `.clear-all-filters__button`
+- `LabelSelector` -> `.label-selector__toggle`, `.label-selector__item`
+
+## JavaScript
+
+- Query by BEM classes: `document.querySelector('.date-range-selector__timezone')`.
+- Scope queries to the nearest component or form when possible: `element.closest('form').querySelector('.search-string-input__term')`.
+- Do not use `document.getElementById(...)` for component behavior when a BEM class hook exists.
+
+## Refactoring Existing Code
+
+- Add BEM classes before changing tests or scripts.
+- Update CSS, JavaScript, and Playwright selectors to use the BEM classes.
+- Preserve existing ids unless there is a clear reason they are safe to remove.
+- Run the relevant build or tests after selector changes.
diff --git a/.agents/skills/btcpayserver-changelog/SKILL.md b/.agents/skills/btcpayserver-changelog/SKILL.md
new file mode 100644
index 0000000..5ab5ad1
--- /dev/null
+++ b/.agents/skills/btcpayserver-changelog/SKILL.md
@@ -0,0 +1,43 @@
+---
+name: btcpayserver-changelog
+description: Use when updating or reviewing Changelog.md in BTCPayServer. Contains release range, inclusion, style, and verification guidance.
+---
+
+# BTCPayServer Changelog
+
+When asked to update or review the changelog, focus on user-visible changes and keep entries concise.
+
+## Release Range
+
+- Compare against the previous release tag, for example `v2.3.9..master` when preparing `2.4.0`.
+- If the changelog branch contains changelog-only commits on top of `master`, compare against `master` to avoid including those commits in the review.
+- Check whether the previous release tag is on the same ancestry path. If not, identify the practical post-release bump commit and compare from there as needed.
+
+## What To Include
+
+- Include features, fixes, improvements, regressions, deprecations, removals, and security-relevant behavior changes that users, admins, plugin authors, API users, or integrators may care about.
+- Include UI fixes when they affect real usage, even if the code change is small.
+- Include permission, authentication, wallet, checkout, Point of Sale, subscription, rate provider, plugin compatibility, and API behavior changes when they affect users or integrators.
+- Include removals and deprecations under `Miscellaneous` unless they fit better under another existing section.
+
+## What To Skip
+
+- Skip purely internal refactors, file moves, test-only changes, warning fixes, dependency bumps for tests, and CI/tooling changes unless they affect users or release operators.
+- Skip very technical route/controller/view-model reshuffling unless it changes public behavior or public API usage.
+- Skip duplicate commits already covered by a previous patch release section.
+
+## Style
+
+- Use short bullet points under sections such as `New features`, `Fixes`, `Improvements`, and `Miscellaneous`.
+- Prefer imperative phrasing: `Add`, `Fix`, `Allow`, `Improve`, `Remove`, `Deprecate`.
+- Keep capitalization consistent with existing entries.
+- Use product terminology consistently, for example `Point of Sale`, `Pull Payments`, `Pull Requests`, `Invoices`, `Apps`, `Keypad Point of Sale`, and `Greenfield API`.
+- Wrap code identifiers and permissions in backticks, for example `` `CanSendStoreEmail` ``.
+- Include PR or issue numbers when available, for example `(#7379)` or `(#7383 #7386)`.
+- Include the contributor handle at the end when known, for example `@NicolasDorier`.
+
+## Verification
+
+- Review the final diff with `git diff -- Changelog.md`.
+- Run `git diff --check -- Changelog.md` to catch whitespace issues.
+- Verify authorship for added entries with `git show --no-patch --format='%h %an <%ae> %s' <commit>` when attribution is not obvious.
diff --git a/.agents/skills/btcpayserver-migrations/SKILL.md b/.agents/skills/btcpayserver-migrations/SKILL.md
new file mode 100644
index 0000000..8b3f955
--- /dev/null
+++ b/.agents/skills/btcpayserver-migrations/SKILL.md
@@ -0,0 +1,15 @@
+---
+name: btcpayserver-migrations
+description: Use when creating or reviewing Entity Framework migrations in BTCPayServer. Contains repository-specific migration generation and cleanup rules.
+---
+
+# BTCPayServer Migrations
+
+## Creating Migrations
+
+- Run `dotnet ef migrations add <migration-name>` to generate the migration.
+- Copy the class attributes from the generated `.Designer.cs` file to the `.cs` migration file.
+- Remove the generated `.Designer.cs` file.
+- Remove the `Down()` method.
+- Do not use `migrationBuilder.IsNpgsql()`; assume PostgreSQL is used.
+- If a migration cannot be generated through `dotnet ef migrations`, add a migration file prefixed by date in the `Migrations` folder, for example `20260525115757_passkey.cs`, and use `migrationBuilder.Sql` to run raw SQL.
diff --git a/.agents/skills/playwright-test-patterns/SKILL.md b/.agents/skills/playwright-test-patterns/SKILL.md
new file mode 100644
index 0000000..676e975
--- /dev/null
+++ b/.agents/skills/playwright-test-patterns/SKILL.md
@@ -0,0 +1,39 @@
+---
+name: playwright-test-patterns
+description: Use when writing or refactoring Playwright tests in BTCPayServer. Covers PMO/Page Model Object usage, selector encapsulation, and avoiding over-engineering.
+---
+
+# Playwright Test Patterns
+
+Use these patterns when writing or refactoring Playwright tests in BTCPayServer.
+
+## Page Model Objects
+
+- Creating Page Model Objects (PMOs) is encouraged when test code repeats UI interactions or assertions.
+- PMOs should make tests more readable by exposing user-level actions and assertions.
+- PMOs should hide repeated selector logic from test bodies.
+- PMOs should expose methods such as `AssertSearchText(value)` or `SelectDateRangePreset(name)` instead of requiring repeated `Expect(...).ToHave...` calls at test call sites.
+- PMOs should use stable selector hooks, preferably BEM class selectors for frontend components.
+
+## Avoid Over-Engineering
+
+- Do not create a PMO when the tested UI is very local to one test class and unlikely to be reused elsewhere.
+- For page-specific controls used only in one test class, prefer small local helpers inside the test class.
+- Keep PMOs focused on reusable components or page flows.
+- Do not add abstraction layers that only wrap one obvious Playwright call unless it meaningfully improves readability or removes repetition.
+
+## Selector Guidance
+
+- Prefer BEM class selectors for reusable UI hooks.
+- Avoid direct ids in Playwright tests for reusable components when BEM hooks exist.
+- Keep page-specific selectors near the page-specific test or PMO.
+- When a selector is used in multiple tests, consider moving it behind a PMO action or assertion.
+
+## Refactoring Existing Tests
+
+- Prefer modifying or extending an existing relevant test over writing a new test.
+- Add a new test only when no existing scenario naturally covers the behavior or when combining scenarios would make the test unclear.
+- First identify repeated interaction/assertion sequences.
+- Move repeated sequences into a PMO when they represent reusable component or page behavior.
+- Keep one-off logic in the test if abstraction would obscure the scenario.
+- Run the relevant test or test project build after refactoring Playwright selectors or PMOs.
diff --git a/.claude b/.claude
new file mode 120000
index 0000000..c0ca468
--- /dev/null
+++ b/.claude
@@ -0,0 +1 @@
+.agents
\ No newline at end of file
diff --git a/AGENTS.md b/AGENTS.md
index 55f7432..7c3a8dc 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,49 +1,8 @@
# Agent Instructions
-## Creating Migrations
+Repository-specific agent guidance has moved to project skills:
-* Run `dotnet ef migrations add <migration-name>` to generate the migration.
-* Copy the attributes from the generated `.Designer.cs` file to the `.cs` migration file.
-* Remove the generated `.Designer.cs` file.
-* Remove the `Down()` method.
-* Do not use `migrationBuilder.IsNpgsql()`; assume PostgreSQL is used.
-* If a migration cannot be generated through `dotnet ef migrations`, add a migration file prefixed by date in the `Migrations` folder, for example `20260525115757_passkey.cs`, and use `migrationBuilder.Sql` to run raw SQL.
+- `.agents/skills/btcpayserver-migrations/SKILL.md`
+- `.agents/skills/btcpayserver-changelog/SKILL.md`
-## Updating `Changelog.md`
-
-When asked to update or review the changelog, focus on user-visible changes and keep entries concise.
-
-### Release Range
-
-* Compare against the previous release tag, for example `v2.3.9..master` when preparing `2.4.0`.
-* If the changelog branch contains changelog-only commits on top of `master`, compare against `master` to avoid including those commits in the review.
-* Check whether the previous release tag is on the same ancestry path. If not, identify the practical post-release bump commit and compare from there as needed.
-
-### What To Include
-
-* Include features, fixes, improvements, regressions, deprecations, removals, and security-relevant behavior changes that users, admins, plugin authors, API users, or integrators may care about.
-* Include UI fixes when they affect real usage, even if the code change is small.
-* Include permission, authentication, wallet, checkout, Point of Sale, subscription, rate provider, plugin compatibility, and API behavior changes when they affect users or integrators.
-* Include removals and deprecations under `Miscellaneous` unless they fit better under another existing section.
-
-### What To Skip
-
-* Skip purely internal refactors, file moves, test-only changes, warning fixes, dependency bumps for tests, and CI/tooling changes unless they affect users or release operators.
-* Skip very technical route/controller/view-model reshuffling unless it changes public behavior or public API usage.
-* Skip duplicate commits already covered by a previous patch release section.
-
-### Style
-
-* Use short bullet points under sections such as `New features`, `Fixes`, `Improvements`, and `Miscellaneous`.
-* Prefer imperative phrasing: `Add`, `Fix`, `Allow`, `Improve`, `Remove`, `Deprecate`.
-* Keep capitalization consistent with existing entries.
-* Use product terminology consistently, for example `Point of Sale`, `Pull Payments`, `Pull Requests`, `Invoices`, `Apps`, `Keypad Point of Sale`, and `Greenfield API`.
-* Wrap code identifiers and permissions in backticks, for example `` `CanSendStoreEmail` ``.
-* Include PR or issue numbers when available, for example `(#7379)` or `(#7383 #7386)`.
-* Include the contributor handle at the end when known, for example `@NicolasDorier`.
-
-### Verification
-
-* Review the final diff with `git diff -- Changelog.md`.
-* Run `git diff --check -- Changelog.md` to catch whitespace issues.
-* Verify authorship for added entries with `git show --no-patch --format='%h %an <%ae> %s' <commit>` when attribution is not obvious.
+Load the relevant skill when creating migrations or updating/reviewing `Changelog.md`.
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.