diff --git a/shared/rules/angular.md b/shared/rules/angular.md new file mode 100644 index 0000000..f3bba29 --- /dev/null +++ b/shared/rules/angular.md @@ -0,0 +1,297 @@ +# Angular Code Guidelines + +* Use modern Angular patterns and current framework conventions. +* Prefer standalone components, directives and pipes for new code. +* Avoid introducing `NgModule` unless the existing project architecture requires it. +* Keep components small and focused. +* Keep templates simple. +* Move complex logic out of templates. +* Keep business logic out of components where practical. +* Prefer services, facades or dedicated domain logic for non-trivial behavior. +* Avoid god components and god services. +* Keep dependencies explicit. +* Prefer composition over inheritance. +* Avoid unnecessary abstractions. +* Avoid unnecessary wrapper components. +* Follow the existing project architecture unless there is a strong reason to change it. + +## Components + +* Use `ChangeDetectionStrategy.OnPush` unless there is a concrete reason not to. +* Prefer signal-based state for local component state. +* Prefer `computed` for derived state. +* Prefer `effect` only for actual side effects. +* Do not use `effect` as a replacement for normal data flow. +* Keep component state minimal. +* Avoid duplicating derived state. +* Prefer immutable state updates. +* Avoid direct mutation of shared state. +* Keep inputs and outputs strongly typed. +* Prefer signal-based inputs and outputs when consistent with the project. +* Avoid unnecessary two-way binding. +* Avoid unnecessary component-to-component coupling. +* Prefer explicit data flow from parent to child and explicit events upward. +* Do not expose internal component state unnecessarily. +* Use lifecycle hooks only when required. +* Avoid complex initialization logic inside constructors. + +## Templates + +* Keep expressions short and readable. +* Do not execute expensive methods from templates. +* Avoid function calls in templates when their result can be derived or cached. +* Avoid complex conditions directly in markup. +* Prefer derived state in TypeScript over repeated template expressions. +* Use Angular control flow syntax such as `@if`, `@for` and `@switch` for new code. +* Always provide stable tracking for repeated collections. +* Avoid deeply nested template structures. +* Split large templates into focused components when it improves maintainability. +* Avoid unnecessary DOM elements. +* Use semantic HTML. +* Prefer native HTML behavior before custom implementations. +* Keep accessibility in mind when choosing elements and interactions. + +## Signals and State + +* Prefer signals for local and synchronous reactive state. +* Prefer `computed` for derived values. +* Keep signals private when external mutation is not intended. +* Expose readonly state where practical. +* Avoid storing values that can be derived from existing state. +* Avoid circular signal dependencies. +* Avoid side effects inside `computed`. +* Keep effects small and deterministic. +* Clean up resources created by effects. +* Do not use global state unless multiple unrelated parts of the application genuinely need it. +* Do not introduce a state-management library without a clear requirement. + +## RxJS + +* Use RxJS for asynchronous streams, events and complex reactive flows. +* Do not use RxJS when simple synchronous signals are sufficient. +* Prefer declarative observable pipelines. +* Avoid nested `subscribe`. +* Avoid manual subscriptions where `async`, signals or framework helpers are sufficient. +* Prefer `takeUntilDestroyed` or equivalent Angular lifecycle integration for manual subscriptions. +* Always consider subscription lifetime. +* Avoid memory leaks from unmanaged subscriptions. +* Use the correct flattening operator for the required semantics. +* Do not use `switchMap`, `mergeMap`, `concatMap` or `exhaustMap` interchangeably. +* Avoid unnecessary `Subject` usage. +* Prefer exposing observables instead of exposing mutable subjects. +* Prefer `BehaviorSubject` only when a current value is actually required. +* Avoid excessive observable chains for simple state. +* Avoid converting repeatedly between signals and observables without need. + +## Dependency Injection + +* Prefer Angular dependency injection for application services. +* Keep injected dependencies minimal. +* Avoid service locator patterns. +* Prefer `inject()` where it improves readability and is consistent with the project. +* Do not inject services that are not used. +* Scope services intentionally. +* Prefer application-wide singletons only for truly shared stateless or coordinated state. +* Avoid storing request-specific or component-specific mutable state in root services. +* Use injection tokens for configuration or abstractions where appropriate. +* Do not create interfaces only to satisfy dependency injection when no abstraction is needed. + +## Services + +* Keep services focused on a clear responsibility. +* Avoid large catch-all services. +* Separate API access, domain logic and UI state where practical. +* Avoid leaking transport models throughout the application. +* Do not expose mutable internal state directly. +* Prefer readonly APIs for state consumers. +* Avoid hidden side effects. +* Keep service methods predictable. +* Do not use services merely to move poorly structured component code elsewhere. + +## HTTP and APIs + +* Keep API access centralized and strongly typed. +* Prefer dedicated API clients or data-access services. +* Do not use `any` for API responses. +* Treat all server responses as untrusted at runtime. +* Validate external data when the contract is security- or correctness-critical. +* Keep DTOs separate from domain models when their responsibilities differ. +* Avoid duplicate API calls. +* Cache only when the invalidation strategy is clear. +* Avoid manual URL string construction when typed helpers or centralized endpoints are available. +* Use interceptors only for cross-cutting concerns. +* Do not put unrelated business logic into HTTP interceptors. +* Handle cancellation where appropriate. +* Handle expected error states explicitly. + +## Forms + +* Prefer reactive forms for non-trivial forms. +* Keep forms strongly typed. +* Avoid untyped forms. +* Keep validation rules centralized and reusable where practical. +* Validate on both client and server where required. +* Never treat client-side validation as a security boundary. +* Keep form state separate from domain state when useful. +* Avoid large components that combine layout, validation, persistence and business logic. +* Display validation errors consistently. +* Preserve user input when recoverable errors occur. + +## Routing + +* Keep route definitions explicit and predictable. +* Prefer lazy loading for larger feature areas. +* Avoid loading large feature bundles eagerly without need. +* Use route guards only for navigation behavior, not as a security boundary. +* Authorization must still be enforced on the backend. +* Keep resolvers focused. +* Avoid expensive work during navigation unless required. +* Keep route parameters strongly typed at application boundaries where practical. +* Do not rely on client-side routing state for sensitive authorization decisions. + +## Performance + +* Use `OnPush`. +* Use stable tracking in loops. +* Avoid unnecessary change detection triggers. +* Avoid repeated expensive template calculations. +* Avoid unnecessary subscriptions. +* Avoid unnecessary DOM rendering. +* Lazy-load large features and heavy dependencies where appropriate. +* Avoid large initial bundles. +* Avoid importing full libraries when only a small part is required. +* Avoid unnecessary deep cloning. +* Avoid unnecessary object and array recreation in hot paths. +* Keep state updates targeted. +* Avoid unnecessary global state updates. +* Measure bundle size and runtime performance before micro-optimizing. +* Prefer architectural improvements over template-level micro-optimizations. + +## Security + +* Treat all external data as untrusted. +* Never bypass Angular sanitization without a verified reason. +* Avoid direct DOM manipulation. +* Avoid `innerHTML` with untrusted content. +* Avoid `bypassSecurityTrust*` unless explicitly required and the input is fully controlled. +* Never expose secrets in frontend code. +* Never store sensitive credentials in the Angular application. +* Do not rely on frontend checks for authorization. +* Enforce authentication and authorization on the backend. +* Avoid leaking sensitive information through logs or error messages. +* Use secure cookie or token handling according to the application's authentication architecture. +* Avoid storing sensitive tokens in insecure browser storage without a deliberate security decision. +* Do not disable security controls for convenience. + +## DOM and Browser APIs + +* Prefer Angular APIs and declarative templates over direct DOM manipulation. +* Use `Renderer2` only when direct rendering abstraction is actually needed. +* Avoid accessing globals directly when it harms testability or SSR compatibility. +* Consider SSR and hydration compatibility for browser-specific code. +* Guard access to `window`, `document`, `localStorage` and similar browser-only APIs when SSR is supported. +* Clean up event listeners, observers and timers. +* Avoid layout thrashing in performance-sensitive code. + +## Accessibility + +* Use semantic HTML. +* Preserve keyboard navigation. +* Ensure interactive elements are actually interactive elements. +* Do not replace buttons with clickable `div` elements. +* Provide labels for form controls. +* Maintain visible focus behavior. +* Use ARIA only when native HTML semantics are insufficient. +* Avoid unnecessary custom widgets. +* Keep accessible names and states synchronized with UI state. + +## Styling + +* Keep styles scoped and predictable. +* Avoid unnecessary global CSS. +* Follow the project's styling strategy consistently. +* Avoid excessive specificity. +* Avoid `!important` unless there is a concrete reason. +* Prefer reusable design tokens and shared styles over duplicated magic values. +* Keep component styles focused on component concerns. +* Avoid styling based on fragile DOM structure. +* Do not mix multiple styling approaches without need. + +## Testing + +* Test behavior, not implementation details. +* Prefer focused component tests. +* Test critical user interactions. +* Test services and domain logic independently where useful. +* Avoid brittle tests coupled to internal structure. +* Avoid excessive mocking. +* Mock external boundaries rather than internal implementation details. +* Keep tests deterministic. +* Avoid time-dependent tests without controlled clocks. +* Avoid network-dependent tests without proper isolation. +* Keep test setup minimal and readable. +* Update tests when refactoring changes structure but not behavior. + +## Architecture + +* Keep UI, application, domain and data-access concerns separated where practical. +* Organize code by feature rather than by technical file type when it improves cohesion. +* Avoid circular dependencies. +* Avoid cross-feature imports without a clear contract. +* Keep shared code genuinely shared. +* Do not move feature-specific logic into generic shared modules. +* Avoid dumping unrelated helpers into global utility files. +* Keep public APIs of feature areas small. +* Avoid exposing internal implementation details across feature boundaries. +* Prefer local ownership of state and logic. + +## Code Quality + +* Use strict TypeScript settings. +* Avoid `any`. +* Avoid unnecessary type assertions. +* Avoid non-null assertions unless safety is guaranteed. +* Prefer modern, readable syntax. +* Use descriptive names. +* Avoid vague names such as `data`, `item`, `value` or `temp` when better names exist. +* Remove dead code. +* Remove unused imports and dependencies. +* Remove commented-out code instead of keeping it in source files. +* Do not add comments unless the user explicitly requests them. +* Treat Angular, TypeScript and lint warnings seriously. +* Do not suppress diagnostics without a concrete reason. +* Prefer correctness, security and maintainability over cleverness. + +## Dependency Rules + +* Prefer Angular and browser platform capabilities before adding third-party libraries. +* Do not add dependencies without a clear benefit. +* Avoid libraries that duplicate existing framework functionality. +* Avoid abandoned or poorly maintained packages. +* Keep Angular package versions aligned. +* Do not mix incompatible Angular package versions. +* Respect the existing lockfile and package manager. +* Avoid unrelated dependency upgrades. + +## Performance Priority + +Prioritize Angular performance work in this order: + +* Application architecture +* Network and API behavior +* Bundle size and lazy loading +* State architecture +* Change detection +* Rendering and DOM complexity +* RxJS and subscription behavior +* Memory allocations +* CPU micro-optimizations + +Never optimize based purely on assumptions. + +## Safety Rule + +* Angular frontend code is never a security boundary. +* Client-side validation, guards, hidden controls and disabled UI elements do not replace backend enforcement. +* Do not bypass Angular's built-in security mechanisms without a verified and explicit reason. +* Prefer safe framework defaults over custom low-level behavior. diff --git a/shared/rules/csharp.md b/shared/rules/csharp.md new file mode 100644 index 0000000..af2cabb --- /dev/null +++ b/shared/rules/csharp.md @@ -0,0 +1,116 @@ +# C# Code Guidelines + +* Write clear, readable, maintainable code first. +* Optimize only based on measurements and profiling. +* Prefer simple solutions over clever abstractions. +* Follow current C# and .NET conventions. +* Prefer immutable data where practical. +* Keep methods small and focused. +* Keep classes focused on a single responsibility. +* Avoid unnecessary inheritance. +* Prefer composition over inheritance. +* Use `sealed` when inheritance is not intended. +* Avoid unnecessary abstractions and wrapper layers. +* Avoid premature generalization. +* Prefer explicit code over hidden magic. +* Avoid unnecessary reflection. +* Avoid unnecessary runtime type checks. +* Avoid unnecessary allocations in hot paths. +* Avoid unnecessary collection copies. +* Avoid unnecessary string allocations. +* Avoid unnecessary LINQ in performance-critical paths. +* Use LINQ where it improves readability and performance is irrelevant. +* Choose collections based on access patterns. +* Preallocate collection capacity when the expected size is known. +* Avoid large mutable structs. +* Use `Span` and related APIs only when they provide a measurable benefit. +* Prefer `Task` over `ValueTask` unless `ValueTask` is justified by profiling. +* Use async only for genuinely asynchronous operations. +* Keep async code async throughout the call chain. +* Avoid `.Result`, `.Wait()` and synchronous blocking of async operations. +* Propagate `CancellationToken` through asynchronous APIs. +* Do not create unnecessary background tasks. +* Limit concurrency when processing large workloads. +* Avoid uncontrolled `Task.WhenAll` over large collections. +* Avoid exceptions for normal control flow. +* Fail fast on invalid arguments and invalid state. +* Avoid swallowing exceptions. +* Preserve meaningful exception context. +* Use dependency injection where dependencies require substitution or lifecycle management. +* Avoid service locator patterns. +* Avoid excessive constructor dependencies. +* Keep application, domain and infrastructure concerns separated. +* Avoid unnecessary cross-layer coupling. +* Prefer explicit dependencies. +* Minimize global and static mutable state. +* Design APIs with clear contracts. +* Prefer strongly typed models over loosely typed dictionaries or dynamic objects. +* Validate input at system boundaries. +* Avoid duplicate validation deep inside trusted internal code. +* Treat external input as untrusted. +* Do not expose internal implementation details through public APIs. +* Avoid leaking sensitive information through logs or exceptions. +* Use structured logging. +* Avoid excessive logging in hot paths. +* Avoid logging sensitive data. +* Prefer database-side filtering, projection and aggregation. +* Do not load data that is not needed. +* Avoid N+1 database queries. +* Use no-tracking queries for read-only EF Core operations where appropriate. +* Keep database round trips minimal. +* Avoid unnecessary serialization and deserialization. +* Reuse expensive resources such as HTTP clients and database infrastructure correctly. +* Do not optimize micro-level CPU operations before fixing architectural, database or I/O bottlenecks. +* Prefer algorithms and data structures with appropriate complexity. +* Measure allocations, GC pressure, CPU usage and latency when investigating performance. +* Write code that is easy to test. +* Avoid tests coupled to implementation details. +* Prefer deterministic behavior. +* Avoid hidden side effects. +* Keep naming consistent and descriptive. +* Avoid abbreviations unless they are established domain terminology. +* Remove dead code instead of keeping it as commented-out code. +* Do not add comments or API documentation unless the user explicitly requests them. +* Follow existing project conventions unless there is a strong reason to change them. +* Do not introduce new libraries when the BCL or existing dependencies already solve the problem adequately. +* Prefer fewer dependencies. +* Keep dependency versions current and supported. +* Treat warnings seriously. +* Do not suppress analyzers without a concrete reason. +* Keep performance improvements readable unless the hot path clearly justifies additional complexity. +* Prefer correctness, maintainability and predictable behavior over theoretical micro-optimizations. + +## C# Style & Safety + +* Prefer modern, readable C# syntax and current .NET conventions. +* Prefer simple, explicit code over outdated or unnecessarily verbose patterns. +* Prefer concrete collection types for parameters, properties and local APIs when no abstraction is required. +* Avoid interface collection types such as `IDictionary`, `IList` or `ICollection` unless polymorphism or API abstraction is actually needed. +* Prefer `Dictionary`, `List`, arrays or other concrete types when the implementation type is known and intentional. +* Prefer strongly typed models over `object`, `dynamic`, loosely typed dictionaries or string-based contracts. +* Validate external input at system boundaries. +* Fail fast on invalid arguments and impossible states. +* Avoid unsafe code unless explicitly required. +* Avoid reflection when a strongly typed solution is practical. +* Avoid hidden side effects and implicit global state. +* Prefer immutable or readonly data where practical. +* Avoid exposing mutable internal collections directly. +* Prefer safe framework APIs over custom low-level implementations. +* Never weaken validation, authorization, certificate checks, encryption or other security controls for convenience. +* Do not log secrets, tokens, credentials or sensitive data. +* Treat all external data as untrusted. +* Prefer correctness and security over minor convenience or micro-optimizations. + +## Performance Priority + +Prioritize performance work in this order: + +* Architecture +* Database access +* Network and I/O +* Algorithms and data structures +* Concurrency +* Allocations and GC pressure +* CPU micro-optimizations + +Never optimize based purely on assumptions. diff --git a/shared/rules/decision-rule.md b/shared/rules/decision-rule.md new file mode 100644 index 0000000..662da0c --- /dev/null +++ b/shared/rules/decision-rule.md @@ -0,0 +1,10 @@ +## Decision Rule + +* Gather evidence from the repository, available tooling, and current technical sources before making technical decisions. +* Make technical implementation and code-style decisions independently when existing code, reliable documentation, or established standards provide sufficient evidence and the decision is reversible. +* Ask the user when technical uncertainty remains material, multiple meaningful options remain, or the decision has a high-impact or difficult-to-reverse effect. +* Ask the user before deciding business behavior, domain rules, validation rules, status transitions, permissions, database rules, error behavior, UI, UX, or other user-visible behavior when the requested behavior is missing, ambiguous, contradictory, or open to interpretation. +* Implement explicitly specified behavior without asking again. +* Ask the user when changing or choosing an API, database model, configuration format, external contract, or compatibility behavior remains ambiguous or has multiple meaningful interpretations. +* Do not invent business requirements or silently resolve contradictions. +* Treat direct user input as the final decision for behavior and requirements. diff --git a/shared/rules/definition-of-done.md b/shared/rules/definition-of-done.md new file mode 100644 index 0000000..a221687 --- /dev/null +++ b/shared/rules/definition-of-done.md @@ -0,0 +1,52 @@ +# Definition of Done + +A task is only considered done when all applicable requirements below are fulfilled. + +## Coding + +* The implementation fully satisfies the requested behavior. +* All relevant acceptance criteria are implemented. +* The work item description is fully addressed. +* The code builds successfully. +* Relevant tests pass. +* New or changed behavior is covered by tests where appropriate. +* No known errors, warnings, regressions, or broken behavior remain. +* The implementation follows the project's coding, architecture, security, and performance guidelines. +* No unrelated changes are included. +* No temporary code, debug output, commented-out code, placeholders, or TODOs remain unless explicitly intended. +* Error handling and edge cases are handled appropriately. +* The implementation is readable, maintainable, and production-ready. +* Existing documentation was not changed automatically. If the code makes it inaccurate, the user was asked before proceeding. +* No new documentation, repository comments, pull request text, or work-item text was created without explicit user instruction. +* Any delegated research, review, or verification is complete and its relevant findings are resolved or reported. + +## Work Items + +A work item is only considered complete when: + +* Every acceptance criterion is fulfilled. +* Every requirement in the description is implemented or otherwise resolved. +* Acceptance criteria and description are checked against the actual implementation, not assumed to be complete. +* No known requirement is left partially implemented. +* No unresolved blocker or relevant defect remains. +* Required tests or validations have been completed successfully. +* Any deviation from the description or acceptance criteria has been explicitly approved by the user. + +## Completion Check + +Before declaring a task complete: + +* Re-read the work item description. +* Re-read all acceptance criteria. +* Compare each requirement against the implemented result. +* Verify the relevant code paths. +* Run applicable builds and tests. +* Check for incomplete or unrelated changes. +* Confirm that the final state matches the requested outcome. + +## Important Rule + +* Do not mark, close, resolve, or otherwise change the state of a work item automatically. +* A task may be technically complete without changing its remote work item state. +* Any Azure DevOps WRITE operation still requires explicit user approval. +* If completion is unclear, requirements conflict, or something is missing, ask the user instead of deciding autonomously. diff --git a/shared/rules/general.md b/shared/rules/general.md new file mode 100644 index 0000000..14345d2 --- /dev/null +++ b/shared/rules/general.md @@ -0,0 +1,32 @@ +# General rules + +## Priority + +Apply instructions in this order: + +1. Direct current user instructions. +2. Non-negotiable security and data-loss protections. +3. Applicable project-specific instructions. +4. These global user-level rules. +5. Existing project conventions. +6. Agent preferences. + +Project instructions may specialize global defaults, but must not weaken security or data-loss protections without explicit user approval. + +## Documentation + +* Never modify existing documentation automatically. +* If a code change would make existing documentation inaccurate or outdated, ask the user before changing the code or documentation. +* Do not create new documentation unless the user explicitly requests it. +* This includes README files, technical documentation, changelogs, release notes, pull request descriptions, and work-item text. + +## Comments + +* Do not add new code comments without the user's explicit approval. +* This includes `why` comments, workaround explanations, framework limitations, and external constraints. +* If a comment appears technically useful or necessary, ask the user before adding it. +* Prefer self-explanatory code and clear names. + +## Language + +* Write code and repository-generated user-facing text in English. diff --git a/shared/rules/git.md b/shared/rules/git.md new file mode 100644 index 0000000..00c0d10 --- /dev/null +++ b/shared/rules/git.md @@ -0,0 +1,167 @@ +# Git Guidelines + +## General Rules + +* Never commit changes unless explicitly instructed to do so. +* Never push changes unless explicitly instructed to do so. +* Never create a pull request unless explicitly instructed to do so. +* Never merge branches unless explicitly instructed to do so. +* Never rebase branches unless explicitly instructed to do so. +* Never amend an existing commit unless explicitly instructed to do so. +* Never create or delete Git tags unless explicitly instructed to do so. +* Never modify remote branches unless explicitly instructed to do so. +* Do not interpret general requests such as "finish this", "implement this", or "fix this" as permission to commit or push. +* Permission to commit does not imply permission to push. +* Permission to push does not imply permission to create or merge a pull request. +* Only perform Git write operations that the user explicitly requested. +* Read-only Git commands may be used when needed to inspect repository state. + +## Repository Safety + +* Always inspect the current Git status before performing Git write operations. +* Never discard uncommitted user changes. +* Never overwrite unrelated changes. +* Never reset, clean, checkout, restore, or revert user changes unless explicitly requested. +* Never use destructive Git operations without explicit instruction. +* Never use `git reset --hard` unless explicitly requested. +* Never use `git clean` unless explicitly requested. +* Never force-push unless explicitly requested. +* Never use `--force` or `--force-with-lease` unless explicitly requested. +* Never rewrite shared history without explicit instruction. +* Never modify `.gitignore` unless required by the task. +* Never commit secrets, credentials, tokens, API keys, private keys, environment files, or other sensitive data. +* Never bypass Git hooks unless explicitly requested. +* Never use `--no-verify` unless explicitly requested. + +## Scope + +* Only stage files related to the requested task. +* Never stage unrelated modified files. +* Prefer staging specific files instead of using broad commands such as `git add .`. +* Do not include generated files unless they are intentionally tracked by the repository. +* Do not include formatting-only changes unrelated to the task. +* Do not modify unrelated files merely to create a cleaner commit. +* Keep commits focused on one logical change. +* Split unrelated changes into separate commits when multiple commits were explicitly requested. + +## Commit Messages + +Use Conventional Commits. + +Format: + +`(): ` + +Allowed common types: + +* `feat`: new functionality +* `fix`: bug fix +* `refactor`: code change without changing external behavior +* `perf`: performance improvement +* `test`: test changes +* `docs`: documentation changes +* `style`: formatting or style-only changes +* `build`: build system or dependency changes +* `ci`: CI/CD changes +* `chore`: maintenance work +* `revert`: revert of an earlier change + +Commit message rules: + +* Use lowercase commit types. +* Keep the subject concise and specific. +* Use imperative wording. +* Do not end the subject with a period. +* Describe what changed, not how hard the work was. +* Avoid vague messages such as `fix stuff`, `update`, `changes`, or `cleanup`. +* Use a scope when it improves clarity. +* Keep each commit limited to one logical purpose. +* Use `!` or a `BREAKING CHANGE:` footer for breaking changes. +* Reference issue or ticket identifiers only when relevant and known. +* Never invent issue numbers, ticket IDs, or references. + +Examples of valid commit messages: + +* `feat(auth): add refresh token rotation` +* `fix(api): handle missing user id` +* `refactor(storage): simplify cache abstraction` +* `perf(database): reduce duplicate queries` +* `test(users): add validation coverage` +* `docs(readme): document local setup` +* `build: update dotnet dependencies` + +## Branches + +* Do not create a branch unless explicitly requested. +* Do not switch branches unless necessary for the requested task. +* Never delete branches unless explicitly requested. +* Never rename branches unless explicitly requested. +* Never assume the target branch for a merge, rebase, or push. +* Preserve the repository's existing branch naming convention. +* If no branch naming convention exists and a branch was explicitly requested, prefer concise names such as: + + * `feat/` + * `fix/` + * `refactor/` + * `chore/` + +## Pulling and Fetching + +* Fetching remote state is allowed when required for inspection. +* Do not pull automatically unless explicitly requested or required for an explicitly requested Git operation. +* Never resolve pull or merge conflicts by discarding user changes. +* Do not automatically rebase after pulling. +* Do not automatically merge remote changes into the current branch. + +## Conflicts + +* Stop before making destructive conflict-resolution decisions. +* Preserve both user work and repository history whenever possible. +* Resolve conflicts only when the correct resolution is clear from the task and surrounding code. +* Do not silently choose one side of a conflict when intent is ambiguous. +* Never use conflict resolution as an excuse to remove unrelated changes. + +## Before an Explicitly Requested Commit + +Before creating a commit: + +* Inspect `git status`. +* Inspect the staged diff. +* Confirm only task-related files are staged. +* Check for accidental secrets or sensitive files. +* Ensure the changes are consistent with the requested task. +* Run relevant tests, checks, or builds when practical. +* Do not include unrelated modifications. +* Use a Conventional Commit message. + +## Before an Explicitly Requested Push + +Before pushing: + +* Confirm that pushing was explicitly requested. +* Confirm the intended branch. +* Confirm the intended remote when multiple remotes exist. +* Ensure the commits being pushed are expected. +* Do not force-push unless explicitly requested. +* Do not push unrelated local commits unintentionally. + +## Autonomous Agent Rule + +The agent may edit files and implement requested changes autonomously. + +The agent must not autonomously: + +* commit +* push +* merge +* rebase +* amend commits +* create pull requests +* create or delete tags +* delete branches +* rewrite Git history +* discard working-tree changes + +These actions require explicit user instruction each time. + +When in doubt, leave the repository changes uncommitted. diff --git a/shared/rules/microsoft.md b/shared/rules/microsoft.md new file mode 100644 index 0000000..b388d12 --- /dev/null +++ b/shared/rules/microsoft.md @@ -0,0 +1,133 @@ +# Azure DevOps & Microsoft Teams Guidelines + +## Core Rule + +* READ operations may be performed autonomously. +* WRITE operations always require explicit user confirmation beforehand. +* Treat all remote data as read-only by default. +* Never perform a WRITE operation without asking first. +* Previous approval does not automatically authorize future WRITE operations. +* If the intended WRITE changes materially after approval, ask again. + +## READ Operations + +READ operations may be performed without confirmation. + +Examples: + +* Read work items +* Read descriptions +* Read comments +* Read pull requests +* Read pipeline status +* Read repository metadata +* Read Teams messages +* Read conversations and threads +* Read meeting information +* Search Azure DevOps +* Search Microsoft Teams +* Inspect statuses, assignments, tags, fields and history +* Analyze retrieved information + +Do not ask for permission before READ operations when they are useful for completing the task. + +## WRITE Operations + +Before every WRITE operation: + +* Explain exactly what will be changed. +* Show the intended content when applicable. +* Ask for explicit confirmation. +* Perform the WRITE only after confirmation. +* Do not assume approval from context or previous actions. + +WRITE operations include any action that changes remote state. + +## Azure DevOps WRITE Operations + +Always ask before: + +* Creating work items +* Editing work items +* Editing titles +* Editing descriptions +* Editing acceptance criteria +* Adding comments +* Replying to comments +* Editing or deleting comments +* Changing status or state +* Opening or reopening work items +* Resolving or closing work items +* Assigning or reassigning work items +* Changing priority, severity, tags, iteration or area +* Modifying links or relations +* Creating or modifying pull requests +* Approving or voting on pull requests +* Completing, merging or abandoning pull requests +* Triggering, retrying or cancelling pipelines +* Modifying pipeline configuration +* Creating or deleting branches +* Modifying repository settings +* Modifying policies, releases, environments or deployments +* Any other operation that changes Azure DevOps data + +## Microsoft Teams WRITE Operations + +Always ask before: + +* Sending messages +* Replying to messages +* Editing messages +* Deleting messages +* Reacting to messages +* Creating posts or announcements +* Creating chats or threads +* Creating or modifying channels +* Creating or modifying meetings +* Adding or removing participants +* Changing memberships +* Changing permissions +* Modifying Teams settings +* Any other operation that changes Microsoft Teams data + +## Important Restrictions + +* Never edit descriptions autonomously. +* Never reply to comments autonomously. +* Never send Teams messages autonomously. +* Never open, close, resolve or reopen items autonomously. +* Never change statuses autonomously. +* Never trigger pipelines autonomously. +* Never approve or merge pull requests autonomously. +* Never perform destructive actions autonomously. + +## Autonomous Agent Rule + +The agent may freely: + +* read +* search +* inspect +* analyze +* summarize + +The agent must ask first before it: + +* creates +* edits +* deletes +* sends +* comments +* replies +* reacts +* assigns +* changes state +* opens +* closes +* approves +* merges +* triggers +* cancels +* modifies any remote data + +When uncertain whether an operation is READ or WRITE, treat it as WRITE and ask first. diff --git a/shared/rules/refactoring.md b/shared/rules/refactoring.md new file mode 100644 index 0000000..d1a7f14 --- /dev/null +++ b/shared/rules/refactoring.md @@ -0,0 +1,117 @@ +# Refactoring Guidelines + +## Core Rule + +* Refactor only when it improves readability, maintainability, correctness, performance, safety, or architecture. +* Do not refactor unrelated code without a concrete reason. +* Do not change behavior unless the refactoring explicitly requires it. +* Preserve existing functionality by default. +* Keep refactorings focused and minimal. +* Prefer simple improvements over large rewrites. + +## Scope + +* Limit changes to the smallest reasonable scope. +* Do not mix unrelated refactorings. +* Do not combine feature work, bug fixes, formatting changes, and broad refactoring unless necessary. +* Avoid repository-wide changes unless explicitly required. +* Do not rename, move, split, or merge files unnecessarily. +* Do not introduce new abstractions without a clear benefit. + +## Behavior Preservation + +* Existing public behavior must remain unchanged unless explicitly requested. +* Preserve API contracts unless a breaking change is explicitly intended. +* Preserve serialization formats, database contracts, configuration keys, routes, and external integrations unless explicitly required. +* Preserve exception behavior where it is part of an existing contract. +* Preserve thread-safety and concurrency behavior. +* Preserve performance characteristics unless the refactoring intentionally improves them. + +## Code Quality + +* Prefer modern, readable C# syntax. +* Reduce unnecessary complexity. +* Remove duplication where doing so improves clarity. +* Prefer clear control flow over clever code. +* Reduce nesting where practical. +* Improve naming when current names are misleading or unclear. +* Prefer strongly typed code. +* Avoid unnecessary interfaces and abstractions. +* Avoid unnecessary wrapper classes and indirection. +* Prefer composition over inheritance. +* Remove dead code when it is clearly unused. +* Remove obsolete comments and commented-out code. +* Keep methods and classes focused. + +## Architecture + +* Respect existing architectural boundaries. +* Do not introduce new layers without a concrete need. +* Avoid circular dependencies. +* Reduce coupling where practical. +* Keep dependencies explicit. +* Do not move business logic into infrastructure or presentation layers. +* Do not weaken encapsulation for convenience. +* Avoid global or static mutable state. + +## Performance + +* Do not trade significant readability for theoretical micro-optimizations. +* Avoid introducing unnecessary allocations in hot paths. +* Avoid unnecessary collection copies. +* Avoid unnecessary LINQ in performance-critical code. +* Preserve or improve algorithmic complexity. +* Measure performance-sensitive refactorings when relevant. +* Do not assume a refactoring is faster without evidence. + +## Safety + +* Do not weaken validation, authorization, authentication, encryption, null-safety, or input handling. +* Preserve or improve error handling. +* Preserve cancellation behavior. +* Preserve disposal and resource lifetime semantics. +* Avoid introducing race conditions. +* Avoid exposing mutable internal state. +* Treat external input as untrusted. +* Do not introduce unsafe code unless explicitly required. + +## Dependencies + +* Do not add new dependencies unless they provide a clear and necessary benefit. +* Prefer existing project dependencies and the .NET BCL. +* Do not replace stable dependencies without a concrete reason. +* Avoid refactorings that increase long-term maintenance cost. + +## Tests + +* Existing relevant tests must continue to pass. +* Update tests when internal structure changes make it necessary. +* Do not delete valid tests merely because they fail after a refactoring. +* Add tests when the refactoring exposes previously untested critical behavior. +* Prefer behavior-based tests over implementation-detail tests. + +## Validation + +After a refactoring: + +* Build the affected project or solution. +* Run relevant tests. +* Check for new warnings. +* Verify affected code paths. +* Review the diff for accidental behavior changes. +* Check that unrelated files were not modified unnecessarily. +* Confirm that the result is simpler or clearer than before. + +## Large Refactorings + +* Break large refactorings into small, understandable steps. +* Avoid big-bang rewrites when incremental changes are practical. +* Keep intermediate states buildable where possible. +* Do not perform broad architectural rewrites without explicit user intent. +* If multiple valid architectural directions exist, ask the user before choosing one. + +## Decision Rule + +* If a refactoring may change externally visible behavior, data contracts, architecture, public APIs, persistence, security, or deployment behavior, ask the user first. +* If the benefit is unclear or the change introduces significant complexity, do not proceed autonomously. +* When uncertain, prefer the smaller and safer refactoring. diff --git a/shared/rules/security.md b/shared/rules/security.md new file mode 100644 index 0000000..f05f96d --- /dev/null +++ b/shared/rules/security.md @@ -0,0 +1,404 @@ +# Security Guidelines + +Security is a default requirement for all code, architecture, configuration and infrastructure changes. + +## Core Principles + +* Prefer secure defaults. +* Apply least privilege everywhere. +* Minimize exposed attack surface. +* Treat all external input as untrusted. +* Never trust client-side validation alone. +* Fail securely. +* Prefer deny-by-default over allow-by-default for sensitive operations. +* Keep security controls explicit and auditable. +* Do not weaken security for convenience. +* Do not bypass security mechanisms to make code easier to implement. +* Do not introduce insecure temporary solutions. +* Prefer simple, well-understood security mechanisms over custom cryptography or clever security logic. + +## Secrets and Credentials + +* Never hardcode passwords, API keys, tokens, connection strings, private keys or secrets. +* Never commit secrets to source control. +* Never log secrets or credentials. +* Never expose secrets in exceptions, diagnostics or UI messages. +* Use secure secret storage appropriate to the environment. +* Prefer short-lived credentials where supported. +* Rotate compromised credentials immediately. +* Do not reuse credentials across environments. +* Keep development, staging and production credentials separate. +* Avoid secrets in URLs, query strings or command-line arguments. +* Do not store secrets in frontend code. +* Do not include real credentials in examples, tests or fixtures. + +## Authentication + +* Use established authentication standards and framework capabilities. +* Do not implement custom authentication protocols without a strong reason. +* Store passwords only using modern password hashing algorithms designed for password storage. +* Never store plaintext passwords. +* Never use reversible encryption for password storage. +* Support secure session expiration. +* Invalidate sessions or tokens when security-sensitive account state changes. +* Protect authentication endpoints against brute-force abuse where applicable. +* Avoid exposing whether an account exists unless required. +* Require stronger authentication for security-sensitive actions where appropriate. + +## Authorization + +* Enforce authorization on the server side. +* Never rely on hidden UI elements, disabled buttons or frontend guards as authorization. +* Check authorization for every sensitive operation. +* Prefer explicit permission checks. +* Use least-privilege roles and permissions. +* Avoid broad administrative permissions unless required. +* Prevent horizontal privilege escalation between users or tenants. +* Prevent vertical privilege escalation between permission levels. +* Verify ownership of resources before access or modification. +* Do not trust identifiers supplied by the client as proof of authorization. + +## Input Validation + +* Validate all input from users, APIs, files, databases, queues, environment variables and external systems. +* Validate type, length, range, format and allowed values. +* Prefer allowlists over denylists. +* Reject unexpected input. +* Normalize input before validation when appropriate. +* Do not rely solely on client-side validation. +* Validate identifiers before using them for resource access. +* Validate uploaded files by content, size and expected type where applicable. +* Do not trust file extensions alone. + +## Injection Prevention + +* Never concatenate untrusted input into SQL. +* Use parameterized queries or ORM parameter binding. +* Never concatenate untrusted input into shell commands. +* Avoid executing shell commands when a direct API is available. +* Validate and escape command arguments when process execution is required. +* Prevent LDAP, XPath, template and expression injection where applicable. +* Avoid dynamic code execution. +* Avoid `eval`, dynamic compilation and equivalent mechanisms unless strictly required. +* Treat template engines and interpreters as security boundaries. + +## Web Security + +* Prevent Cross-Site Scripting by using framework escaping and sanitization. +* Never inject untrusted HTML directly. +* Avoid bypassing framework sanitization. +* Protect state-changing browser requests against CSRF where applicable. +* Use secure cookies for sensitive session data. +* Use `HttpOnly` for authentication cookies where possible. +* Use `Secure` cookies in HTTPS environments. +* Configure `SameSite` appropriately. +* Use appropriate Content Security Policy where applicable. +* Avoid leaking sensitive data through referrers or URLs. +* Validate redirect targets to prevent open redirects. +* Protect against clickjacking where applicable. + +## API Security + +* Authenticate sensitive endpoints. +* Authorize every protected operation. +* Validate all request payloads. +* Apply reasonable request-size limits. +* Apply pagination and bounded queries. +* Apply rate limiting where abuse is possible. +* Avoid exposing internal models directly when this leaks implementation details. +* Return only data the caller is authorized to access. +* Do not expose stack traces or internal exception details. +* Avoid excessive information in error responses. +* Version public APIs intentionally. +* Protect administrative endpoints separately where appropriate. + +## Data Protection + +* Collect only data that is actually required. +* Minimize storage of sensitive data. +* Classify sensitive data explicitly. +* Encrypt sensitive data in transit. +* Encrypt sensitive data at rest where appropriate. +* Do not implement custom encryption algorithms. +* Use established cryptographic libraries. +* Do not use obsolete cryptographic algorithms. +* Do not use hardcoded encryption keys. +* Use cryptographically secure random number generation for security-sensitive values. +* Avoid exposing personal or sensitive data in logs. +* Delete sensitive data when it is no longer required. + +## Cryptography + +* Never design custom cryptographic primitives. +* Use current, established cryptographic standards. +* Use authenticated encryption when confidentiality and integrity are required. +* Verify signatures before trusting signed content. +* Validate certificates correctly. +* Never disable certificate validation. +* Never accept all TLS certificates. +* Do not downgrade TLS security. +* Use secure randomness for tokens, nonces, identifiers and keys. +* Never use predictable random generators for security-sensitive values. + +## Tokens and Sessions + +* Treat tokens as secrets. +* Keep token lifetime as short as practical. +* Validate issuer, audience, signature and expiration where applicable. +* Do not accept unsigned tokens unless explicitly designed and safe. +* Do not trust token contents before validation. +* Avoid storing long-lived access tokens in insecure browser storage. +* Rotate refresh tokens where appropriate. +* Revoke compromised tokens where possible. +* Prevent replay attacks where the protocol requires it. + +## File Security + +* Validate file names and paths. +* Prevent path traversal. +* Never concatenate untrusted input directly into filesystem paths. +* Restrict file access to intended directories. +* Use generated server-side file names where appropriate. +* Enforce file size limits. +* Validate uploaded content. +* Do not execute uploaded files. +* Store uploads outside executable web roots where applicable. +* Handle archive extraction safely. +* Prevent zip-slip and equivalent path traversal attacks. +* Avoid following untrusted symbolic links where security-sensitive. + +## Serialization + +* Treat deserialized input as untrusted. +* Avoid insecure polymorphic deserialization. +* Avoid deserializing arbitrary runtime types. +* Use explicit schemas or known DTOs. +* Restrict type resolution. +* Do not deserialize executable objects or behavior. +* Validate deserialized data before use. +* Avoid insecure legacy serializers. + +## Database Security + +* Use parameterized queries. +* Use least-privilege database accounts. +* Do not use administrative database accounts for normal application traffic. +* Restrict schema modification permissions in runtime accounts. +* Protect connection strings. +* Avoid exposing raw database errors. +* Limit query size and result sets. +* Prevent tenant data leakage. +* Verify tenant boundaries in every relevant query. +* Use transactions where integrity requires atomicity. + +## Logging and Monitoring + +* Never log secrets. +* Never log passwords. +* Never log authentication tokens. +* Avoid logging sensitive personal data. +* Use structured logging. +* Include security-relevant context without exposing sensitive values. +* Log authentication and authorization failures where appropriate. +* Log suspicious or high-risk actions where appropriate. +* Avoid log injection by treating user input as data. +* Do not let logging failures break critical application behavior. +* Ensure logs have appropriate access controls. + +## Error Handling + +* Fail securely. +* Do not expose internal stack traces to users. +* Do not reveal implementation details unnecessarily. +* Preserve diagnostic detail internally where safe. +* Avoid different error responses that reveal sensitive existence checks where not required. +* Do not swallow security-relevant exceptions. +* Do not continue execution after critical validation or authorization failures. + +## Dependencies + +* Keep dependencies minimal. +* Prefer maintained and widely used packages. +* Avoid abandoned packages. +* Avoid unnecessary dependencies for trivial functionality. +* Keep dependencies updated with security patches. +* Review dependency changes before adoption. +* Do not blindly update major versions without compatibility review. +* Remove unused dependencies. +* Treat transitive dependencies as part of the attack surface. +* Verify package identity before installation. +* Avoid untrusted package sources. +* Respect lockfiles. + +## Supply Chain Security + +* Pin dependency versions where appropriate. +* Protect build and deployment pipelines. +* Do not expose CI/CD credentials. +* Use least privilege for pipeline identities. +* Review third-party actions, plugins and build scripts. +* Avoid executing untrusted build scripts. +* Verify artifacts and sources where practical. +* Keep generated artifacts traceable to source. +* Do not publish secrets in build logs or artifacts. + +## Configuration + +* Use secure production defaults. +* Do not enable debug mode in production. +* Do not expose development endpoints in production. +* Separate environment-specific configuration. +* Validate security-sensitive configuration at startup. +* Fail startup when mandatory security configuration is missing. +* Do not silently fall back to insecure settings. +* Protect configuration files containing sensitive values. + +## Network Security + +* Use HTTPS for sensitive or authenticated communication. +* Do not disable TLS validation. +* Restrict outbound network access where practical. +* Restrict inbound services to required ports and interfaces. +* Use timeouts for network operations. +* Limit retries to avoid amplification or denial-of-service behavior. +* Validate remote endpoints where SSRF is possible. +* Do not allow arbitrary user-controlled URLs for privileged server-side requests. +* Block access to internal network ranges when handling untrusted remote URLs where applicable. + +## SSRF Prevention + +* Treat user-controlled URLs as dangerous. +* Validate schemes. +* Prefer allowlisted hosts. +* Resolve and verify target addresses where necessary. +* Prevent access to localhost, metadata endpoints and internal networks where not explicitly required. +* Revalidate after redirects. +* Limit redirects. +* Apply request timeouts and response-size limits. + +## Concurrency and Resource Abuse + +* Bound concurrency. +* Avoid unbounded task creation. +* Avoid unbounded queues. +* Limit request sizes. +* Limit collection sizes when processing external input. +* Apply timeouts to external operations. +* Apply cancellation where practical. +* Prevent expensive operations from being triggered repeatedly without limits. +* Protect endpoints against denial-of-service through algorithmic complexity. +* Avoid user-controlled regular expressions that may cause catastrophic backtracking. + +## Memory Safety and Resource Management + +* Dispose files, streams, sockets and other resources correctly. +* Prevent resource leaks. +* Avoid retaining sensitive data in memory longer than necessary. +* Avoid unsafe code unless explicitly required. +* Review pointer and memory operations carefully. +* Avoid exposing raw memory or buffers across trust boundaries. +* Clear sensitive buffers where warranted. + +## Multi-Tenant Systems + +* Treat tenant boundaries as security boundaries. +* Scope every tenant-owned query explicitly. +* Never trust tenant identifiers from the client without authorization. +* Prevent cross-tenant cache leakage. +* Prevent cross-tenant logging or diagnostics leakage. +* Keep tenant-specific secrets isolated. +* Test horizontal privilege escalation explicitly. + +## Frontend Security + +* Assume frontend code and data are visible to the user. +* Never embed secrets in frontend applications. +* Never rely on frontend checks for authorization. +* Treat browser storage as potentially accessible to malicious scripts. +* Avoid storing sensitive long-lived tokens unnecessarily. +* Escape or sanitize untrusted content. +* Do not bypass framework security controls without explicit justification. + +## Desktop Application Security + +* Treat local files and IPC input as untrusted where applicable. +* Do not assume local users or processes are trusted. +* Avoid storing secrets in plaintext configuration. +* Protect locally cached sensitive data. +* Validate update packages and downloaded executables. +* Do not execute arbitrary files or commands from untrusted input. +* Use least privilege and avoid unnecessary elevation. + +## Security-Sensitive Changes + +Changes affecting any of the following require additional scrutiny: + +* Authentication +* Authorization +* Cryptography +* Secrets +* User permissions +* File access +* Process execution +* Network access +* Input validation +* Serialization +* Database access +* Payment or financial data +* Personal or confidential data +* Admin functionality +* Deployment or infrastructure security + +For security-sensitive changes: + +* Prefer established framework functionality. +* Review trust boundaries. +* Review failure behavior. +* Review privilege requirements. +* Review input validation. +* Review logging for data leakage. +* Review backward compatibility for security implications. +* Add or update relevant security tests. + +## Security Testing + +* Test authorization failures. +* Test invalid and malicious input. +* Test boundary values. +* Test unauthenticated access. +* Test unauthorized resource access. +* Test cross-user and cross-tenant access where applicable. +* Test expired and invalid credentials. +* Test malformed payloads. +* Test path traversal where files are involved. +* Test injection risks where interpreters or databases are involved. +* Test rate and resource limits where abuse is realistic. +* Preserve regression tests for discovered security issues. + +## Agent Rules + +* Never intentionally weaken security controls without explicit user instruction. +* Never disable certificate validation, authentication, authorization, validation or security middleware to solve a problem. +* Never add hardcoded secrets. +* Never expose sensitive data for debugging convenience. +* Never bypass a security check because it blocks implementation. +* Never assume trusted input without a clearly defined trust boundary. +* Never silently choose a less secure implementation because it is easier. +* If a requested change creates a meaningful security risk, clearly identify the risk before proceeding. +* If requirements are ambiguous in a security-sensitive area, ask the user instead of making an autonomous security decision. + +## Priority Order + +Prioritize security decisions in this order: + +* Prevent unauthorized access +* Protect sensitive data +* Preserve integrity +* Minimize privileges +* Minimize attack surface +* Validate trust boundaries +* Maintain availability +* Preserve auditability +* Optimize usability and performance only within acceptable security constraints + +Security must not be traded away for convenience without an explicit and informed decision. diff --git a/shared/rules/typescript.md b/shared/rules/typescript.md new file mode 100644 index 0000000..7f37ef1 --- /dev/null +++ b/shared/rules/typescript.md @@ -0,0 +1,160 @@ +# TypeScript Code Guidelines + +* Write clear, readable, maintainable code first. +* Prefer modern TypeScript and current ECMAScript syntax. +* Keep code simple and explicit. +* Avoid clever or overly abstract solutions. +* Follow the existing project style and architecture. +* Enable strict TypeScript settings where possible. +* Prefer `strict: true`. +* Avoid `any`. +* Prefer precise types over broad types. +* Prefer `unknown` over `any` for untrusted or unknown values. +* Narrow types explicitly before use. +* Prefer strongly typed models over loose objects. +* Avoid excessive type assertions. +* Avoid non-null assertions unless safety is guaranteed. +* Prefer discriminated unions for state and variant modeling. +* Prefer literal unions over arbitrary strings. +* Prefer enums only when they provide a clear benefit. +* Prefer `readonly` where mutation is not required. +* Prefer immutable data where practical. +* Avoid unnecessary mutation. +* Avoid global mutable state. +* Keep functions small and focused. +* Keep modules focused on a clear responsibility. +* Prefer composition over inheritance. +* Avoid unnecessary classes when functions and plain objects are sufficient. +* Avoid unnecessary interfaces and abstractions. +* Prefer concrete object types when no abstraction is required. +* Use interfaces primarily when extension, implementation contracts, or declaration merging is actually useful. +* Prefer `type` aliases for unions, compositions, mapped types, and local data models. +* Avoid unnecessary wrapper types. +* Avoid excessive generic complexity. +* Keep generic constraints explicit and meaningful. +* Avoid deeply nested conditional or mapped types unless they provide clear value. +* Prefer readable types over type-system cleverness. +* Avoid duplicated type definitions. +* Derive types from existing sources when practical. +* Do not duplicate backend contracts manually when generated or shared types are available. +* Prefer explicit return types for public APIs and non-trivial functions. +* Prefer inference for simple local variables. +* Avoid unnecessary annotations when inference is obvious. +* Prefer `const` by default. +* Use `let` only when reassignment is required. +* Avoid `var`. +* Prefer optional chaining and nullish coalescing where appropriate. +* Do not use `||` when `0`, `false`, or empty strings are valid values. +* Handle `null` and `undefined` intentionally. +* Avoid mixing `null` and `undefined` without a clear convention. +* Prefer early returns over excessive nesting. +* Avoid deeply nested control flow. +* Avoid overly large functions. +* Avoid hidden side effects. +* Keep pure logic pure where practical. +* Prefer deterministic behavior. +* Avoid implicit runtime coercion. +* Use strict equality. +* Avoid unnecessary object spreading in hot paths. +* Avoid unnecessary array copies. +* Avoid unnecessary intermediate arrays. +* Avoid repeated `.map()`, `.filter()`, or `.reduce()` chains in performance-critical paths. +* Use array methods when they improve readability and performance is not critical. +* Prefer appropriate data structures such as `Map` and `Set` when lookup behavior requires them. +* Avoid O(n²) patterns when a better structure is practical. +* Measure performance before micro-optimizing. +* Avoid unnecessary JSON serialization and parsing. +* Avoid unnecessary deep cloning. +* Avoid `JSON.parse(JSON.stringify(...))` as a cloning strategy. +* Prefer platform APIs such as `structuredClone` when deep cloning is actually required. +* Avoid synchronous blocking operations in server-side hot paths. +* Prefer asynchronous APIs for I/O. +* Always handle rejected promises. +* Avoid floating promises. +* Use `await` when sequencing is required. +* Use `Promise.all` for independent operations when safe. +* Limit concurrency for large workloads. +* Avoid uncontrolled `Promise.all` over very large collections. +* Support cancellation with `AbortSignal` where applicable. +* Clean up event listeners, timers, subscriptions, streams, and resources. +* Avoid memory leaks caused by retained closures or listeners. +* Do not swallow exceptions. +* Preserve useful error context. +* Use typed domain errors where they improve handling. +* Avoid exceptions for normal control flow. +* Validate external input at system boundaries. +* Never trust API payloads, query parameters, environment variables, storage data, or user input based solely on TypeScript types. +* Use runtime validation for untrusted external data. +* Do not assume compile-time types provide runtime safety. +* Prefer schema validation when external contracts are complex. +* Never expose secrets, tokens, credentials, or sensitive data. +* Do not log sensitive information. +* Avoid unsafe dynamic property access. +* Avoid `eval`, `Function`, and dynamic code execution. +* Avoid unsafe HTML injection. +* Sanitize untrusted HTML when rendering HTML is required. +* Avoid weakening TLS, authentication, authorization, CSP, validation, or other security controls. +* Treat all external data as untrusted. +* Prefer secure defaults. +* Do not disable security checks for convenience. +* Avoid prototype pollution risks when merging untrusted objects. +* Prefer allowlists over denylists for security-sensitive validation. +* Keep dependencies minimal. +* Prefer built-in platform APIs over adding small utility dependencies. +* Do not add dependencies without a clear reason. +* Avoid abandoned or unnecessary packages. +* Keep dependencies current and supported. +* Respect lockfiles. +* Do not manually modify generated lockfile content. +* Avoid broad dependency upgrades unrelated to the task. +* Use ESM or the project's existing module system consistently. +* Avoid mixing module systems without necessity. +* Prefer named exports unless the project convention favors default exports. +* Keep import paths consistent. +* Remove unused imports and exports. +* Avoid circular dependencies. +* Keep frontend, domain, application, and infrastructure concerns separated where applicable. +* Keep API and transport models separate from domain logic when necessary. +* Do not leak implementation details through public APIs. +* Avoid unnecessary public exports. +* Keep module boundaries intentional. +* Write code that is easy to test. +* Prefer behavior-based tests. +* Avoid tests coupled to implementation details. +* Mock only external boundaries or expensive dependencies where practical. +* Keep tests deterministic. +* Avoid time-, network-, and environment-dependent tests without proper isolation. +* Remove dead code instead of keeping it as commented-out code. +* Do not add comments unless the user explicitly requests them. +* Use descriptive naming. +* Avoid vague names such as `data`, `obj`, `item`, `temp`, or `value` when more precise names are available. +* Avoid abbreviations unless they are established domain terminology. +* Keep naming conventions consistent. +* Treat lint and TypeScript errors seriously. +* Do not suppress ESLint or TypeScript diagnostics without a concrete reason. +* Avoid `@ts-ignore`. +* Prefer `@ts-expect-error` only when the error is intentional and documented. +* Do not disable lint rules globally for local problems. +* Prefer correctness, security, maintainability, and predictable behavior over micro-optimizations. + +## Performance Priority + +Prioritize performance work in this order: + +* Architecture +* Network and API usage +* Database access +* Algorithms and data structures +* Rendering and state updates +* Concurrency +* Memory allocations +* CPU micro-optimizations + +Never optimize based purely on assumptions. + +## Safety Rule + +* Compile-time type safety is not runtime validation. +* Validate all external and untrusted data. +* Do not use `any`, type assertions, non-null assertions, or disabled compiler checks to bypass real type problems. +* Prefer making invalid states unrepresentable where practical. diff --git a/shared/rules/ui-ux.md b/shared/rules/ui-ux.md new file mode 100644 index 0000000..2584140 --- /dev/null +++ b/shared/rules/ui-ux.md @@ -0,0 +1,306 @@ +# UI & UX Guidelines + +* Design for clarity first. +* Prefer simple, modern and predictable interfaces. +* Optimize for fast understanding and low cognitive load. +* Every screen should have a clear primary purpose. +* Every important action should be easy to discover. +* Prefer familiar interaction patterns over novel ones. +* Do not require users to learn unnecessary custom behavior. +* Keep layouts visually calm and structured. +* Use consistent spacing, typography, colors and interaction patterns. +* Avoid visual noise. +* Avoid decorative elements that do not improve usability. +* Avoid unnecessary complexity in navigation and workflows. +* Minimize the number of steps required to complete common tasks. +* Keep related information and actions close together. +* Group content logically. +* Use clear visual hierarchy. +* Make primary actions visually distinct from secondary actions. +* Avoid giving multiple actions equal visual priority when one is clearly more important. +* Use whitespace intentionally. +* Prefer readable line lengths and sufficient spacing. +* Avoid dense walls of content. +* Avoid oversized empty areas that reduce information efficiency. +* Keep important information visible without unnecessary scrolling where practical. + +## Navigation + +* Navigation must be predictable and consistent. +* Users should always understand where they are. +* Users should always understand how to go back. +* Avoid hidden navigation when visible navigation is practical. +* Keep navigation depth shallow where possible. +* Use clear and descriptive navigation labels. +* Do not use ambiguous icons without labels when meaning is not obvious. +* Preserve navigation state when users return to a previous view where practical. +* Avoid resetting filters, search state or scroll position unnecessarily. +* Avoid unexpected redirects. +* Do not change navigation behavior between similar screens without a clear reason. + +## Actions + +* Use clear action labels. +* Prefer verbs that describe the actual outcome. +* Avoid vague labels such as `OK`, `Submit`, `Proceed` or `Execute` when a more specific label is possible. +* Make destructive actions clearly distinguishable. +* Keep dangerous actions away from common actions. +* Require confirmation for destructive or difficult-to-reverse actions. +* Do not require unnecessary confirmation for safe, reversible actions. +* Disable unavailable actions when the reason is obvious. +* Explain why an action is unavailable when it is not obvious. +* Avoid actions that appear clickable but are not. +* Provide immediate visual feedback after user actions. +* Prevent accidental duplicate submissions. +* Make loading, success and failure states visible. + +## Forms + +* Keep forms as short as practical. +* Ask only for information that is actually required. +* Group related fields together. +* Use clear field labels. +* Do not rely on placeholders as the only label. +* Use appropriate input controls for the expected value. +* Provide useful defaults where safe and predictable. +* Preserve user input when validation or network errors occur. +* Validate fields at useful moments without interrupting normal input. +* Show validation errors close to the affected field. +* Explain how to fix invalid input. +* Avoid technical validation messages. +* Clearly mark optional fields where useful. +* Avoid asking the same information multiple times. +* Use autocomplete and autofill where appropriate. +* Make keyboard navigation logical. +* Use sensible tab order. +* Support Enter and Escape behavior where users expect it. + +## Content and Language + +* Use plain, concise language. +* Prefer user terminology over internal technical terminology. +* Avoid jargon unless the target users are expected to understand it. +* Use consistent naming for the same concepts. +* Do not rename concepts between screens. +* Keep button labels, headings and descriptions concise. +* Put the most important information first. +* Avoid unnecessary explanatory text. +* Add explanation only where users may reasonably be confused. +* Error messages should explain what happened and what the user can do next. +* Avoid blaming the user. +* Avoid exposing stack traces, exception names or internal implementation details. + +## Feedback and System State + +* Always communicate important system state. +* Show loading states for operations that are not immediate. +* Avoid indefinite loading indicators without context. +* Use progress indicators for longer operations where progress can be measured. +* Clearly distinguish loading, empty, error and success states. +* Do not leave blank screens where an empty state is expected. +* Empty states should explain what the user can do next. +* Show success feedback when the result is not otherwise obvious. +* Keep transient notifications concise. +* Do not hide important errors in temporary notifications. +* Preserve actionable errors until the user has had a chance to understand them. +* Do not silently fail. +* Do not silently discard user input. + +## Responsiveness + +* The interface should feel responsive at all times. +* Provide immediate feedback after interaction. +* Avoid blocking the entire interface when only one section is loading. +* Prefer localized loading states. +* Use optimistic UI only when failures can be handled safely. +* Avoid layout jumps during loading. +* Reserve space for content where practical. +* Keep animations short and functional. +* Do not use animations that delay task completion. +* Respect reduced-motion preferences. +* Avoid unnecessary transitions and visual effects. + +## Visual Design + +* Prefer modern, clean and restrained visual design. +* Use a consistent design system. +* Keep typography hierarchy clear. +* Maintain sufficient contrast. +* Use color intentionally. +* Do not rely on color alone to communicate state. +* Keep the number of accent colors limited. +* Avoid excessive gradients, shadows and decorative effects. +* Use rounded corners, borders and elevation consistently. +* Keep icons stylistically consistent. +* Use familiar icons for familiar actions. +* Pair unclear icons with text labels. +* Avoid tiny click targets. +* Keep interactive targets large enough for comfortable use. +* Maintain consistent alignment. +* Avoid arbitrary spacing values. +* Prefer reusable spacing and sizing tokens. + +## Accessibility + +* Accessibility is part of the default design, not an optional enhancement. +* Use semantic controls and elements. +* Ensure full keyboard usability. +* Maintain visible focus indicators. +* Use sufficient color contrast. +* Do not rely solely on hover interactions. +* Do not rely solely on color to indicate status. +* Provide accessible names for controls. +* Keep focus order logical. +* Move focus intentionally after dialogs, navigation or major state changes. +* Support screen readers where applicable. +* Use ARIA only when native semantics are insufficient. +* Respect reduced-motion and system accessibility preferences. +* Avoid flashing or distracting content. + +## Responsive Design + +* Design for the available viewport instead of fixed screen sizes. +* Prioritize important content on smaller screens. +* Avoid horizontal scrolling unless the content genuinely requires it. +* Keep controls usable on touch devices. +* Do not simply shrink desktop layouts. +* Adapt navigation and layout intentionally for smaller screens. +* Preserve core functionality across supported screen sizes. +* Avoid hiding important actions solely because space is limited. +* Test common breakpoints and extreme content lengths. + +## Tables and Data-Dense Views + +* Use tables only for genuinely tabular data. +* Keep column names concise. +* Align numeric data consistently. +* Make sorting and filtering discoverable. +* Preserve filter and sort state where useful. +* Do not overload tables with too many actions. +* Prefer a clear primary row action and secondary contextual actions. +* Keep important columns visible. +* Allow horizontal scrolling only when necessary. +* Use pagination, virtualization or incremental loading for large data sets. +* Provide clear empty states. +* Avoid showing unnecessary columns by default. +* Use sensible formatting for dates, numbers and units. + +## Search and Filtering + +* Search should behave predictably. +* Make active filters visible. +* Make filters easy to remove. +* Provide a clear way to reset filters. +* Preserve search and filter state when navigating back where practical. +* Avoid requiring users to configure many filters before seeing results. +* Use sensible defaults. +* Clearly distinguish no results from loading or errors. +* Suggest recovery options when no results are found. + +## Dialogs and Modals + +* Use dialogs only when interruption is justified. +* Avoid stacking dialogs. +* Keep dialogs focused on one decision or task. +* Use clear titles. +* Keep primary and secondary actions obvious. +* Make cancellation easy. +* Support Escape where appropriate. +* Do not use dialogs for information that belongs inline. +* Avoid large workflows inside modal dialogs. +* Do not close dialogs unexpectedly while users are entering data. + +## Destructive Actions + +* Clearly label destructive actions. +* Use confirmations for irreversible or high-impact operations. +* Explain the consequence before confirmation. +* Prefer reversible actions when possible. +* Offer undo where practical. +* Do not use generic confirmation text for destructive operations. +* Make the safe action visually distinct. +* Do not preselect destructive choices. + +## Error Prevention + +* Prevent invalid actions before they occur where practical. +* Use constraints and suitable controls instead of relying only on validation errors. +* Provide sensible defaults. +* Confirm only high-impact decisions. +* Warn users before losing unsaved changes. +* Do not clear entered data unexpectedly. +* Avoid ambiguous state transitions. +* Make dependencies between fields or actions visible. + +## Consistency + +* Similar problems should have similar UI solutions. +* Similar actions should use the same wording and placement. +* Do not introduce custom patterns when an existing pattern already solves the problem. +* Reuse components and design tokens. +* Keep interaction behavior consistent across the application. +* Preserve platform conventions unless there is a strong reason not to. + +## User Control + +* Keep users in control of important actions. +* Do not perform surprising destructive actions automatically. +* Do not change user data without a clear action or established behavior. +* Make automatic behavior visible when it materially affects the user. +* Allow users to cancel long-running operations where practical. +* Allow recovery from mistakes where possible. +* Avoid dark patterns. +* Never manipulate users into actions they did not intend. + +## Progressive Disclosure + +* Show the most important options first. +* Hide advanced complexity until it is needed. +* Do not overwhelm users with every possible setting at once. +* Keep advanced options discoverable. +* Avoid forcing expert workflows on normal users. +* Avoid hiding frequently used functionality behind excessive menus. + +## Performance Perception + +* Optimize perceived performance as well as actual performance. +* Show useful content as early as possible. +* Avoid blocking initial rendering on non-critical data. +* Use skeletons only when they improve comprehension. +* Avoid fake progress. +* Do not use loading animations to mask avoidable slowness. +* Keep interactions responsive even while background work continues. + +## Defaults + +* Choose safe and sensible defaults. +* Defaults should match the most common expected user intent. +* Avoid defaults with destructive consequences. +* Preserve user preferences when appropriate. +* Do not force repeated configuration for common workflows. + +## Design Decision Rule + +* Every UI element should have a clear purpose. +* Every additional interaction adds cognitive cost. +* Prefer removing complexity over explaining unnecessary complexity. +* Prefer familiar patterns over clever ones. +* Prefer fewer clear choices over many ambiguous choices. +* Prefer predictable behavior over surprising automation. +* If a design decision introduces ambiguity, unnecessary complexity, or multiple equally valid UX directions, ask the user instead of deciding autonomously. + +## Priority Order + +Prioritize UI/UX decisions in this order: + +* Correctness +* Clarity +* Safety +* Accessibility +* User control +* Task efficiency +* Consistency +* Responsiveness +* Visual polish + +Visual polish must never reduce usability. diff --git a/shared/rules/wpf.md b/shared/rules/wpf.md new file mode 100644 index 0000000..ce0e074 --- /dev/null +++ b/shared/rules/wpf.md @@ -0,0 +1,375 @@ +# WPF Code Guidelines + +* Use modern C# and current .NET/WPF conventions. +* Keep UI, application logic and domain logic clearly separated. +* Prefer MVVM for non-trivial views. +* Keep code-behind minimal. +* Use code-behind only for view-specific behavior that does not belong in the ViewModel. +* Avoid business logic in views. +* Avoid direct service access from controls. +* Keep dependencies explicit and testable. +* Prefer composition over inheritance. +* Avoid unnecessary abstractions and framework wrappers. +* Follow the existing project architecture unless there is a strong reason to change it. + +## MVVM + +* Keep ViewModels focused on presentation state and commands. +* Do not put UI element references into ViewModels. +* Do not access `Window`, `UserControl`, `DispatcherObject` or visual tree elements from ViewModels. +* Avoid direct navigation, dialogs or message boxes from ViewModels without an abstraction when testability matters. +* Prefer explicit application services for navigation, dialogs and external interactions. +* Keep domain logic outside ViewModels. +* Do not use ViewModels as general-purpose service containers. +* Keep ViewModel dependencies minimal. +* Prefer immutable or readonly state where practical. +* Avoid duplicated derived state. +* Keep state transitions predictable. + +## Data Binding + +* Prefer data binding over manual UI synchronization. +* Use strongly typed properties. +* Use appropriate binding modes. +* Prefer `OneWay` when two-way updates are not required. +* Use `TwoWay` only when the UI must modify the source. +* Avoid unnecessary `UpdateSourceTrigger=PropertyChanged` for expensive operations. +* Keep binding paths simple and stable. +* Avoid deeply nested binding paths. +* Do not hide broken bindings. +* Treat binding errors as real defects. +* Use `FallbackValue` and `TargetNullValue` only when they reflect intended behavior. +* Avoid excessive converters. +* Prefer exposing correctly shaped state from the ViewModel over complex converter logic. +* Avoid `MultiBinding` when simpler state modeling is clearer. +* Do not put business logic into converters. + +## Property Change Notifications + +* Implement property change notifications consistently. +* Avoid raising `PropertyChanged` unnecessarily. +* Raise notifications only when values actually change. +* Keep dependent property notifications explicit. +* Avoid hidden notification chains that are difficult to reason about. +* Prefer reusable base implementations only when they reduce duplication without obscuring behavior. +* Do not use reflection-based notification mechanisms unless there is a concrete benefit. + +## Commands + +* Prefer commands over click handlers for ViewModel-driven actions. +* Keep command execution focused. +* Avoid putting large workflows directly inside command implementations. +* Keep `CanExecute` logic cheap. +* Refresh command availability only when relevant state changes. +* Avoid command implementations with hidden side effects. +* Handle async commands safely. +* Prevent accidental duplicate execution when an async action must not run concurrently. +* Never use `async void` except for true event handlers. + +## Async and Threading + +* Keep async operations asynchronous throughout the call chain. +* Avoid `.Result`, `.Wait()` and other synchronous blocking of async work. +* Do not block the UI thread. +* Run I/O asynchronously. +* Move expensive CPU work off the UI thread only when necessary. +* Marshal UI updates back to the UI thread when required. +* Keep Dispatcher usage minimal and explicit. +* Do not use the Dispatcher to hide incorrect threading design. +* Support `CancellationToken` for cancellable long-running operations. +* Cancel obsolete work when views or selections change. +* Prevent race conditions caused by overlapping async operations. +* Handle exceptions from background operations explicitly. + +## UI Thread + +* Treat the UI thread as a scarce resource. +* Avoid expensive loops, parsing, serialization, database access or network calls on the UI thread. +* Avoid excessive Dispatcher invocations. +* Batch UI updates where practical. +* Do not update UI-bound collections excessively in tight loops. +* Avoid synchronous waits on background work. +* Keep rendering-related callbacks lightweight. + +## Collections + +* Use `ObservableCollection` only when collection change notifications are required. +* Do not use `ObservableCollection` as a general-purpose collection. +* Use `List` or other suitable collections for non-observable internal data. +* Avoid replacing entire observable collections when incremental updates are sufficient. +* Avoid thousands of individual collection notifications when a bulk update is more appropriate. +* Keep collection mutations on the correct thread. +* Avoid exposing mutable internal collections unnecessarily. +* Prefer read-only views where consumers should not modify data. + +## XAML + +* Keep XAML readable and focused. +* Avoid excessively large view files. +* Split complex views into focused controls when it improves maintainability. +* Use resources for repeated values and styles. +* Avoid magic numbers in XAML. +* Keep styles and templates consistent. +* Avoid excessive inline styling. +* Prefer reusable resources over duplicated markup. +* Avoid deeply nested panels. +* Keep visual trees as shallow as practical. +* Use semantic control choices. +* Avoid unnecessary containers. +* Do not overuse triggers when simpler state representation is possible. +* Keep templates understandable. +* Avoid XAML tricks that make behavior hard to discover. + +## Layout + +* Prefer `Grid` for structured layouts. +* Use `StackPanel` only where its layout behavior is actually appropriate. +* Avoid unnecessary nested panels. +* Avoid fixed sizes unless the design requires them. +* Prefer responsive sizing with `Auto` and `*`. +* Avoid layout configurations that cause excessive measure/arrange passes. +* Be careful with large visual trees inside scrolling containers. +* Avoid disabling virtualization accidentally. + +## Virtualization + +* Keep UI virtualization enabled for large collections. +* Do not use container layouts that disable virtualization without a reason. +* Avoid wrapping large virtualized item lists in additional scrolling containers. +* Use virtualizing panels where appropriate. +* Verify virtualization when displaying large data sets. +* Avoid rendering thousands of controls simultaneously. +* Prefer paging, incremental loading or virtualization for very large data sets. + +## Resources and Styles + +* Use shared resources for repeated styles, brushes, templates and dimensions. +* Keep resource dictionaries focused. +* Avoid giant global resource dictionaries. +* Prefer feature-level resources when styles are not truly global. +* Use `StaticResource` by default. +* Use `DynamicResource` only when runtime resource replacement is required. +* Avoid excessive dynamic resource lookups. +* Keep theme resources separated from application logic. +* Avoid hardcoded colors and dimensions when design tokens or resources already exist. + +## Dependency Properties + +* Use dependency properties only when WPF property-system behavior is required. +* Do not use dependency properties as a replacement for normal CLR properties. +* Keep metadata and callbacks lightweight. +* Avoid expensive work in property-changed callbacks. +* Avoid callbacks with hidden side effects. +* Validate or coerce values only when the control contract requires it. +* Do not expose mutable default values in dependency property metadata. + +## Attached Properties and Behaviors + +* Use attached properties and behaviors for reusable view-specific behavior. +* Do not use them to hide business logic. +* Keep behaviors focused and predictable. +* Clean up event handlers when behaviors are detached. +* Avoid global attached-property state. +* Prefer explicit behavior over complex XAML hacks. + +## Events + +* Avoid unnecessary event subscriptions. +* Unsubscribe from long-lived publishers when required. +* Prevent memory leaks from event handlers. +* Prefer weak events where publisher lifetime significantly exceeds subscriber lifetime. +* Keep event handlers small. +* Do not use events as hidden global communication channels. +* Avoid excessive event chaining. + +## Memory Management + +* Watch for memory leaks caused by: + + * Event subscriptions + * Timers + * Static references + * Long-lived services + * Cached views + * Closures + * Collection views + * Binding-related references +* Dispose resources correctly. +* Stop timers and background work when no longer needed. +* Avoid retaining closed windows or unloaded views. +* Do not keep unnecessary references to visual elements. +* Profile memory when long-running applications continuously grow. + +## Windows and Dialogs + +* Keep window lifecycle explicit. +* Avoid creating duplicate windows unintentionally. +* Do not keep hidden windows alive without a reason. +* Separate dialog logic from business logic. +* Prefer dialog services when ViewModels need to request user interaction. +* Keep ownership relationships explicit. +* Avoid application shutdown behavior that depends on accidental window lifetime. + +## Navigation + +* Keep navigation state explicit. +* Avoid coupling ViewModels directly to concrete views. +* Avoid service locator patterns for view resolution. +* Keep navigation history intentional. +* Dispose or release navigation targets when they are no longer required. +* Do not retain entire navigation graphs unnecessarily. + +## Validation + +* Validate user input at the appropriate boundary. +* Keep validation logic out of XAML when it becomes complex. +* Prefer reusable validation rules or ViewModel validation for non-trivial cases. +* Display validation errors consistently. +* Do not rely on UI validation as a security boundary. +* Validate again at backend or domain boundaries when required. +* Preserve user input on recoverable errors. + +## Performance + +* Keep the UI thread responsive. +* Minimize visual tree depth. +* Keep virtualization enabled. +* Avoid unnecessary bindings. +* Avoid unnecessary converters. +* Avoid unnecessary resource lookups. +* Avoid unnecessary property change notifications. +* Avoid frequent full collection refreshes. +* Avoid loading large datasets eagerly. +* Avoid loading large images at full resolution when unnecessary. +* Freeze `Freezable` objects where practical. +* Reuse immutable resources where appropriate. +* Avoid unnecessary animations. +* Avoid high-frequency timers on the UI thread. +* Measure startup time, UI responsiveness, memory usage and rendering performance before micro-optimizing. + +## Images and Media + +* Load images at an appropriate resolution. +* Avoid decoding images significantly larger than their displayed size. +* Release streams and file handles correctly. +* Avoid locking image files unintentionally. +* Cache images only when there is a clear memory strategy. +* Avoid keeping large bitmaps alive unnecessarily. +* Prefer frozen image resources when they are immutable. + +## Security + +* Treat all external input as untrusted. +* Never expose secrets, credentials or tokens in UI code. +* Do not store secrets in configuration files committed to source control. +* Avoid leaking sensitive information through logs, dialogs or exception messages. +* Validate file paths and external resources. +* Do not execute external processes or files without explicit validation. +* Avoid insecure deserialization. +* Do not weaken TLS, authentication or certificate validation. +* Prefer secure defaults. +* Never disable security controls for convenience. + +## File and Process Access + +* Validate file paths before use. +* Avoid assuming files or directories exist. +* Handle permissions and locked files gracefully. +* Avoid arbitrary shell execution. +* Quote and validate process arguments safely. +* Do not concatenate untrusted input into shell commands. +* Avoid elevated privileges unless explicitly required. +* Clean up temporary files when appropriate. + +## Error Handling + +* Handle expected errors explicitly. +* Do not swallow exceptions. +* Preserve useful exception context. +* Avoid showing raw technical exceptions directly to end users. +* Log enough information for diagnosis without exposing sensitive data. +* Keep user-facing error messages clear and actionable. +* Avoid using exceptions for normal control flow. +* Ensure background exceptions are observed. + +## Logging + +* Use structured logging. +* Avoid excessive logging on the UI thread. +* Do not log every property change or binding update. +* Never log secrets, tokens, credentials or sensitive user data. +* Include relevant context for operational failures. +* Avoid logging the same exception repeatedly at multiple layers. + +## Architecture + +* Keep presentation, application, domain and infrastructure concerns separated. +* Avoid direct database access from views or ViewModels. +* Avoid direct HTTP access from controls. +* Keep external integrations behind focused services. +* Avoid circular dependencies. +* Keep feature boundaries clear. +* Do not create shared utility classes for unrelated functionality. +* Keep shared code genuinely reusable. +* Minimize global state. +* Avoid static service access. + +## Dependency Injection + +* Use dependency injection where lifecycle management, substitution or testability benefits from it. +* Avoid service locator patterns. +* Keep constructor dependencies minimal. +* Do not inject dependencies that are not used. +* Choose service lifetimes intentionally. +* Do not make stateful services global without a concrete reason. +* Avoid introducing interfaces solely for dependency injection when no abstraction is needed. + +## Testing + +* Keep ViewModels testable without a UI thread where practical. +* Test behavior rather than implementation details. +* Test domain and application logic independently from WPF. +* Avoid brittle tests coupled to XAML structure. +* Keep UI automation tests focused on critical flows. +* Mock external boundaries rather than internal details. +* Keep tests deterministic. +* Avoid real network, database or filesystem dependencies in unit tests unless explicitly intended. + +## Code Quality + +* Use nullable reference types. +* Prefer modern, readable C# syntax. +* Avoid unnecessary interfaces and abstractions. +* Prefer concrete types where no abstraction is required. +* Use descriptive names. +* Remove dead code. +* Remove commented-out code. +* Do not add comments unless the user explicitly requests them. +* Treat compiler, analyzer and binding warnings seriously. +* Do not suppress warnings without a concrete reason. +* Prefer correctness, responsiveness, security and maintainability over cleverness. + +## Performance Priority + +Prioritize WPF performance work in this order: + +* UI architecture +* UI thread blocking +* Data loading and I/O +* Virtualization +* Visual tree complexity +* Binding and notification frequency +* Rendering and images +* Memory retention and leaks +* Allocations +* CPU micro-optimizations + +Never optimize based purely on assumptions. + +## Safety Rule + +* The UI must remain responsive. +* Do not block the UI thread with I/O or expensive CPU work. +* Do not bypass validation or security controls for convenience. +* Do not introduce hidden cross-thread access. +* Prefer predictable, explicit and testable UI behavior.