{"id":50576653,"url":"https://github.com/the-erratic-ensemble/meridian.analyzer","last_synced_at":"2026-06-04T23:00:24.739Z","repository":{"id":362546804,"uuid":"1259621591","full_name":"the-erratic-ensemble/Meridian.Analyzer","owner":"the-erratic-ensemble","description":"Roslyn analyzers for ASP.NET Core codebases with opinionated readability, architecture, security, reliability, and performance rules.","archived":false,"fork":false,"pushed_at":"2026-06-04T21:10:13.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T21:19:17.828Z","etag":null,"topics":["code-quality","csharp","dotnet","nuget-package","roslyn-analyzer","static-analysis"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/the-erratic-ensemble.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T17:33:35.000Z","updated_at":"2026-06-04T21:06:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/the-erratic-ensemble/Meridian.Analyzer","commit_stats":null,"previous_names":["the-erratic-ensemble/meridian.analyzer"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/the-erratic-ensemble/Meridian.Analyzer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-erratic-ensemble%2FMeridian.Analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-erratic-ensemble%2FMeridian.Analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-erratic-ensemble%2FMeridian.Analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-erratic-ensemble%2FMeridian.Analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/the-erratic-ensemble","download_url":"https://codeload.github.com/the-erratic-ensemble/Meridian.Analyzer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-erratic-ensemble%2FMeridian.Analyzer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33923181,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-quality","csharp","dotnet","nuget-package","roslyn-analyzer","static-analysis"],"created_at":"2026-06-04T23:00:14.999Z","updated_at":"2026-06-04T23:00:24.718Z","avatar_url":"https://github.com/the-erratic-ensemble.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Meridian.Analyzer\n\n`Meridian.Analyzer` is a Roslyn analyzer package for ASP.NET Core codebases with opinionated readability, architecture, security, reliability, and performance rules.\n\n## Quick Start\n\nInstall the published analyzer package into a project:\n\n```bash\ndotnet add package Meridian.Analyzer\n```\n\nOr add an explicit package reference:\n\n```xml\n\u003cItemGroup\u003e\n  \u003cPackageReference Include=\"Meridian.Analyzer\" Version=\"0.2.*\" PrivateAssets=\"all\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\n## Repository Layout\n\n- `src/Meridian.Analyzer/`: analyzer project, rule implementations, helpers, and Roslyn release tracking files\n- `tests/Meridian.Analyzer.Tests/`: analyzer behavior tests\n- `docs/`: maintainer guidance, examples, and per-rule documentation\n- `LICENSE`: MIT license for the repository and published package metadata\n\n## Documentation\n\n- Usage examples: [docs/usage-example.md](docs/usage-example.md)\n- Maintainer guide: [docs/guide.md](docs/guide.md)\n- Per-rule documentation: [docs/rules/](docs/rules/)\n\n## Package Facts\n\n- Analyzer project: `src/Meridian.Analyzer/Meridian.Analyzer.csproj`\n- Test project: `tests/Meridian.Analyzer.Tests/Meridian.Analyzer.Tests.csproj`\n- Diagnostic prefix: `MER`\n- Category namespaces: `Meridian.Readability`, `Meridian.Security`, `Meridian.Architecture`, `Meridian.Reliability`, `Meridian.Performance`\n- Packaging status: published on `nuget.org`\n\n## Local Checks\n\n- Local test run: `dotnet test tests/Meridian.Analyzer.Tests/Meridian.Analyzer.Tests.csproj -c Release`\n- Local package smoke check: `dotnet pack src/Meridian.Analyzer/Meridian.Analyzer.csproj -c Release -o artifacts`\n\nRun these from this repo before publishing or sending a change for review.\n\n## Configure Severity\n\nConfigure analyzer severities in your consuming project's `.editorconfig`:\n\n```ini\n[*.cs]\ndotnet_diagnostic.MER0001.severity = warning\ndotnet_diagnostic.MER0002.severity = warning\n```\n\nYou can enable as many or as few rules as you want. Each rule doc explains what it reports and how to refactor away from it.\n\n## Notes\n\n- `nuget.org` is a public feed.\n- Some rules encode opinionated architectural conventions. Review the rule docs before enabling large sets as build warnings in an existing codebase.\n\n## Current Rules\n\n| Rule | Diagnostic ID | Category | Preferred refactor |\n| --- | --- | --- | --- |\n| [Ternary in initializer payload branches](docs/rules/MER0001.md) | `MER0001` | Readability | Stage the payload branch in a named local or helper before building the initializer |\n| [Broad nested try/catch fallback flow](docs/rules/MER0002.md) | `MER0002` | Readability | Extract the inner fallback branch into a helper or flatten the exception-handling flow |\n| [Unsafe output-cache usage](docs/rules/MER0003.md) | `MER0003` | Security | Remove `[OutputCache]` or replace it with no-store caching unless you have a clearly safe cache policy |\n| [Missing explicit controller policy](docs/rules/MER0004.md) | `MER0004` | Security | Declare class-level or action-level policies on admin and high-risk controllers |\n| [Admin controller shape mismatch](docs/rules/MER0005.md) | `MER0005` | Security | Align admin controllers on `Admin*Controller`, `api/admin`, and `AdminControllerBase` |\n| [Controller service location](docs/rules/MER0006.md) | `MER0006` | Architecture | Use constructor injection or `[FromServices]` instead of action-body service location |\n| [Raw configuration reads](docs/rules/MER0007.md) | `MER0007` | Reliability | Move raw reads to typed options, startup guards, or provider adapters |\n| [Startup bypass flag containment](docs/rules/MER0008.md) | `MER0008` | Security | Move `MERIDIAN_SKIP_*` reads behind `StartupGuards` or typed startup-skip options |\n| [Missing controller cancellation token](docs/rules/MER0009.md) | `MER0009` | Reliability | Add `CancellationToken` to async actions and avoid `CancellationToken.None` in request code |\n| [Direct time and delay APIs](docs/rules/MER0010.md) | `MER0010` | Reliability | Use a clock abstraction or `TimeProvider` for runtime time or delay work |\n| [Static mutable runtime state](docs/rules/MER0011.md) | `MER0011` | Reliability | Move static mutable state from controllers or handlers into injectable bounded services |\n| [Health-check registration parity](docs/rules/MER0012.md) | `MER0012` | Reliability | Register every source `Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck` through health-check registration |\n| [Layering violations](docs/rules/MER0013.md) | `MER0013` | Architecture | Move dependencies back to the intended layer |\n| [Model ownership drift](docs/rules/MER0014.md) | `MER0014` | Architecture | Keep DTOs feature-local and entities in dedicated entity folders |\n| [String helper usage](docs/rules/MER0015.md) | `MER0015` | Readability | Use shared string helpers in in-memory code |\n| [Ad hoc JSON options](docs/rules/MER0016.md) | `MER0016` | Architecture | Move ad hoc JSON options into shared profiles or a named factory |\n| [Unbounded EF materialisation](docs/rules/MER0017.md) | `MER0017` | Performance | Add obvious `Where`, `Take`, or `Skip` bounds before async materialisation |\n| [Raw SQL outside persistence code](docs/rules/MER0018.md) | `MER0018` | Security | Keep SQL in persistence code and prefer interpolated APIs over raw APIs |\n| [Direct ProblemDetails construction](docs/rules/MER0019.md) | `MER0019` | Reliability | Use shared ProblemDetails helpers from controller actions |\n| [Controller data access](docs/rules/MER0020.md) | `MER0020` | Architecture | Delegate repository, DbContext, and EF work to services or facades |\n| [Non-Serilog runtime logging](docs/rules/MER0021.md) | `MER0021` | Reliability | Use Serilog in runtime code and keep framework logging at the edges |\n| [Direct Redis keyspace scans](docs/rules/MER0022.md) | `MER0022` | Performance | Route `IServer.Keys` scans through a dedicated bounded helper |\n| [Detached runtime tasks](docs/rules/MER0023.md) | `MER0023` | Reliability | Give background work an explicit lifetime, cancellation path, and observable failure path |\n| [Queryable string-extension predicates](docs/rules/MER0024.md) | `MER0024` | Reliability | Replace `StringExtensions.IsNullOr*` inside queryable or expression-returning methods with translatable query guards |\n| [Empty is-pattern braces](docs/rules/MER0025.md) | `MER0025` | Readability | Replace empty property-pattern braces with shared nullable helpers or explicit null checks when behavior matches |\n\n## Rule-Addition Checklist\n\nBefore landing `MER0002+` or any later rule, update these surfaces in the same change:\n\n1. Analyzer implementation under `src/Meridian.Analyzer/`\n2. Positive and negative tests under `tests/Meridian.Analyzer.Tests/`\n3. Rule documentation under `docs/rules/`\n4. The rule index in this `README.md`\n5. `docs/guide.md` or `docs/usage-example.md` when the docs or maintainer flow changed\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthe-erratic-ensemble%2Fmeridian.analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthe-erratic-ensemble%2Fmeridian.analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthe-erratic-ensemble%2Fmeridian.analyzer/lists"}