Legacy practices that lower your Quality Framework score. Do not introduce them in new code or PRs.
Grouping via NgModule instead of standalone components and Nx libraries. Use standalone + feature libs.
Relying on Zone.js for change detection when targeting modern Angular performance. If you must keep zones, document why and set a migration milestone—do not claim full NG1/NG2 pass.
NgRx/Redux caching every HTTP list (invoices, members) when resource() + port methods suffice. Global signal stores are fine for UI chrome (theme, sidebar), not for every API response.
Injecting HttpClient, Supabase, Firebase, or Stripe directly in feature components. Inject ports only; SDKs live in adapters.
implements CanActivate classes instead of canActivateFn functional guards.
Maintaining tailwind.config.js + PostCSS-only pipeline when on Tailwind v4—use CSS-first config and @tailwindcss/vite where applicable.
PR templates with lint/test/docs checkboxes not backed by CI. Every architectural rule worth stating should be machine-enforced (especially import boundaries).
README claims L2 Production-ready without published self-assessment, production auth, or boundary enforcement.
Hiding admin buttons without documenting that server/RLS/API must enforce permissions. Always document S9.
Binding templates to SupabaseUser, Stripe types, etc. Map to domain types in adapters first.
Importing InjectionToken from @angular/core in the ports layer. Prefer abstract classes as port tokens (see A1).
useClass: isProd ? ProdAdapter : MockAdapter with both adapters statically imported — bundles both SDKs. Use environment file replacement or separate provider files.
Using effect() to sync parent input → local state. Prefer computed() or linkedSignal() (NG6).
Runtime enum emit and poor JSON ergonomics. Use string unions and as const objects (TS6).
environment.prod.ts file replacement without runtime config.json — blocks immutable Docker promote (TS8 L2).
Relying on slow Playwright suites for domain rules that belong in port tests. Use the testing trophy: ports first, mocked UI second, E2E last (T1, T4).
Targeting [ng-reflect-name] or similar — removed from DOM in Angular 21. Use stable data-testid attributes.
Parallel E2E workers mutating one database without tenant isolation or teardown — causes flaky CI. Use per-worker seeds, RLS, or TRUNCATE hooks (T1).
Demanding high Lighthouse scores on authenticated dashboards while ignoring WCAG keyboard flows and INP. Use axe on primary flows (P1) and zoneless for responsiveness (NG1/NG2).
Claiming L2 with meta-tag CSP, JWT in localStorage, and no cookie/BFF migration path — label demo tier or implement S1/S2/S5 production path.
Removing a focused element via @if without restoring focus — disorients keyboard users. Use effect() or explicit focus restore (P4, P11).
New users land on empty shell with no onboarding — fails SaaS5 and PLG activation. Route to create-org / checklist flow.
LLM-generated agent configs without human curation — higher token cost and lower task success than curated AGENTS.md (D1).
Filing vulnerability reports as public GitHub issues — use SECURITY.md private disclosure (D4).
Staying on 0.x.y for years signals instability to enterprise buyers — ship 1.0.0 when install path is stable (D5).
Violations should be caught in code review and, where possible, ESLint/Nx rules. See rubric/ for positive criteria.