The catalog
Every dimension the CAI measures.
The standard is composed of 127 dimensions across 10 lenses. Each is a definition — what it measures and how it's evaluated — pinned to a rubric version. This catalog is the standard's vocabulary; the spec documents how each folds into the score.
Code Health · 22 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
D1 |
Cyclomatic Complexity | How tangled the control flow is — methods with many branches are hard to test and change. | When this is weak, the code is full of tangled, heavily branching methods that are hard to test and risky to change, so even small changes take longer and break things more often. | tool |
D2 |
Cognitive Complexity | How hard the code is for a person to follow, beyond raw branching. | When this is weak, the code is hard for a developer to follow, so understanding it before changing it takes longer and mistakes are more likely. | tool |
D3 |
God Classes | Over-large classes that try to do too much ("god classes"). | When this is weak, oversized classes try to do too much at once, making them a bottleneck that several developers cannot safely work on in parallel. | tool |
D4 |
Code Duplication | Copy-pasted code that should be shared instead. | When this is weak, the same logic is copy-pasted in several places, so a fix or change must be made repeatedly and it is easy to miss a copy and reintroduce a bug. | tool |
D17 |
Explicit Debt | Acknowledged debt left in the code — TODOs, dead code, suppressed warnings. | When this is weak, the team has left acknowledged debt in the code — TODOs, dead code and suppressed warnings — that signals unfinished work you will eventually have to pay down. | tool |
D18 |
Solution Shape | Whether the solution is laid out in a sensible, conventional structure. | When this is weak, the solution is not laid out in a conventional structure, so a new developer takes longer to find their way around and onboarding costs more. | tool |
D39 |
IL Efficiency | IL Efficiency | tool | |
GD1 |
Unfinished & placeholder codemeta | Unreviewed-generation residue: shipped members still throwing NotImplementedException, and placeholder string literals left in non-test, non-generated code. Scored as a quality signature, never as a claim about authorship. | When this is weak, the code still contains shipped methods that throw "not implemented" and placeholder text left in place, meaning features look present but do not actually work. | tool |
IC1 |
Incompleteness & stubsmeta | Unfinished work detected by code SHAPE, not keywords: members that only throw a "not implemented" exception, methods that take inputs and return a constant, async methods that never await, dead `if (false)` / `#if false` branches, and skeleton types most of whose members are holes. A real, objective slice of technical debt. | When this is weak, parts of the code are unfinished by their very shape — stubs, methods that ignore their input, async methods that never wait, dead branches — so the delivery is less complete than it appears. | tool |
R1 |
Type Safetymeta | How much of the frontend is typed TypeScript vs untyped JavaScript. | When this is weak, much of the frontend is untyped JavaScript rather than typed TypeScript, so whole classes of mistakes slip through to runtime instead of being caught while coding. | tool |
R2 |
Cyclomatic Complexitymeta | Per-function cyclomatic/cognitive complexity from the token-level function scanner (D-386) — real branching, not a regex heuristic. | When this is weak, individual frontend functions are heavily branching and tangled, so they are hard to test and risky to change. | tool |
R3 |
Large Filesmeta | How many components/modules exceed the large-file threshold. | When this is weak, several frontend components or modules are oversized, making them harder to understand and a bottleneck for parallel work. | tool |
R7 |
Dead Codemeta | Files unreachable from every application/tooling/test entry point, and exports nothing imports (module-graph reachability, D-386). | When this is weak, the frontend carries dead code — files and exports nothing else uses — that adds noise, inflates the build and slows down anyone reading the code. | tool |
R10 |
Code Duplicationmeta | Copy-pasted token-identical blocks across the frontend (the D4 clone algorithm over JS/TS tokens, D-386). | When this is weak, identical blocks of frontend code are copy-pasted across the codebase, so the same change has to be made in many places and copies are easily missed. | tool |
X1 |
Async correctnessmeta | Whether the code avoids sync-over-async (deadlock-prone blocking on tasks) and async void. | When this is weak, asynchronous code is written in deadlock-prone ways (blocking on tasks, async void), which can cause the application to hang or crash under load. | tool |
X2 |
Cancellation propagationmeta | Whether async methods accept a CancellationToken so work can be cancelled (adoption curve). | When this is weak, long-running operations cannot be cancelled cleanly, so the system keeps doing work no one is waiting for and is harder to shut down responsively. | tool |
X3 |
Exception handlingmeta | Whether exceptions are handled rather than silently swallowed or rethrown with lost stack traces. | When this is weak, errors are silently swallowed or rethrown with their origin lost, so real failures go unnoticed and are far harder to diagnose when they surface. | tool |
X4 |
Structured loggingmeta | Whether log calls use message templates (queryable) rather than interpolated strings. | When this is weak, log messages are built as plain interpolated strings rather than structured templates, so production logs are hard to search and filter when you are trying to find a problem. | tool |
X5 |
Nullable reference typesmeta | Whether nullable reference types are enabled and not undermined by heavy `!` suppression. | When this is weak, the compiler's null-safety checks are off or undermined by suppression, so null-related crashes that the language could have prevented reach production instead. | tool |
X6 |
Hand-rolled structured-format parsingmeta | Whether JSON/XML is parsed with regex/string hacks while a real parser is already referenced in the same project — a classic source of silent data bugs. | tool | |
X7 |
Silent fallback defaultsmeta | Whether parse/lookup failure paths return hard-coded constants with no logging or throw — failures that convert data errors into silent behavior changes. | tool | |
X8 |
JS interop contractmeta | Whether string-named JS interop bindings resolve against the first-party JavaScript, and whether anything guards the boundary against renames. | tool |
Architecture · 20 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
D5 |
Coupling | Whether volatile projects sit underneath others that depend on them (so their churn ripples upward), and whether project dependencies form cycles. A widely-depended-on but stable shared/kernel project is healthy, not penalised. | When this is weak, the parts of the system depend tightly on each other and form circular dependencies, so a change in one place forces changes in several others and the structure resists growth. | tool |
D6 |
Cohesion (LCOM4) | Whether a class's methods are focused on a single responsibility. | When this is weak, individual classes mix several unrelated responsibilities, making them harder to understand, test and change in isolation. | tool |
D7 |
Architectural Integrity | Whether the code respects its intended layering / architecture rules. | When this is weak, the code does not respect its own intended layering, so the structure on paper no longer matches reality and the design erodes over time. | tool |
D22 |
Internal API Consistency | Whether the internal API surface is consistent and coherent. | When this is weak, the system's internal interfaces are inconsistent, so developers cannot rely on familiar patterns and each part has to be learned from scratch. | LLM · advisory |
D23 |
Boundary Type-Coupling | Whether domain types (IDs, enums, value objects) leak across bounded-context boundaries. | When this is weak, domain types leak across module boundaries, so the parts of the system that should be independent become entangled and cannot evolve separately. | tool |
D26 |
Project Cohesion | Whether each project is a focused, coherent unit rather than an oversized grab-bag. | When this is weak, individual projects have become oversized grab-bags rather than focused units, blurring responsibilities and making the codebase harder to reason about. | tool |
D27 |
Navigability | How far you must trace to follow a call — low indirection and co-located slices read easier. | When this is weak, following a single call means tracing through many layers of indirection, so understanding even simple behaviour takes a developer much longer. | tool |
D35 |
Change Coupling | Whether files that change together actually belong together — pairs that repeatedly co-change in git history despite having no explicit code dependency, surfacing the hidden/logical coupling (and boundaries in the wrong place) a static scan can't see. | tool | |
AX1 |
Captive dependenciesmeta | Whether any singleton service captures a scoped/transient dependency — a silent lifetime/threading bug. | When this is weak, long-lived services hold on to short-lived dependencies — a silent lifetime bug that can cause subtle, hard-to-reproduce errors under concurrent use. | tool |
AX2 |
Stateful singletonsmeta | Whether singleton services avoid mutable shared instance state that concurrent callers would race on. | When this is weak, shared single-instance services keep mutable state that concurrent users can race on, leading to intermittent corruption that is very hard to track down. | tool |
AX3 |
Project dependency cyclesmeta | Whether the project-reference graph is acyclic (cycles block independent build/deploy and signal eroding boundaries). | When this is weak, the projects depend on each other in cycles, so they cannot be built or deployed independently and the architectural boundaries are eroding. | tool |
AX4 |
Dependency directionmeta | Whether dependencies point inward (Domain ← Application ← Infrastructure/Web) — the clean-architecture dependency rule, checked across the project graph. | When this is weak, dependencies point the wrong way through the layers, so the core business logic is tied to technical details and becomes harder to test and replace. | tool |
AX5 |
Architecture & structuremeta | Whether the codebase has a recognisable, scale-appropriate structure (a named architectural style, or modular enough for its size) rather than being an ad-hoc ball of mud. | When this is weak, the codebase has no recognisable, scale-appropriate structure, so it reads as an ad-hoc tangle that is hard to navigate and grow. | tool |
AX6 |
Interface segregationmeta | Whether interfaces stay focused rather than fat — the Interface-Segregation principle (SOLID 'I'). | When this is weak, interfaces have grown fat with unrelated members, forcing callers to depend on methods they do not use and making the contracts harder to change. | tool |
AX7 |
Slice cohesionmeta | Whether feature slices stay independent (no direct cross-slice references) — the discipline that makes vertical-slice architecture pay off. | When this is weak, feature slices reach directly into each other instead of staying independent, so a change to one feature can unexpectedly break another. | tool |
AX8 |
Test isolationmeta | Whether production projects stay free of references to test projects — tests may depend on production, never the reverse. | tool | |
AX9 |
CQS / query puritymeta | Whether read (query) handlers stay side-effect-free — a query that writes persistent state or raises events breaks CQS and makes reads unsafe to retry, cache, or route to a read replica. | tool | |
AX10 |
Code compositionmeta | How the codebase splits by code ROLE — domain, application, infrastructure, test, generated. The significance map behind the knowledge/coupling weighting, and a DDD signal in its own right: a thin domain core under fat infrastructure is the anemic-domain smell, quantified. | tool | |
R9 |
Circular Importsmeta | Import cycles in the module graph (D-386) — files that can only be understood and changed together. | When this is weak, frontend files import each other in cycles, so they can only be understood and changed together — a tightly knotted area that resists refactoring. | tool |
R11 |
Import Boundariesmeta | Conformance to the detected frontend architecture layout (feature-sliced / layered src) plus cross-package deep-import rules (D-386). | When this is weak, the frontend ignores its own intended layout and reaches across package boundaries with deep imports, so the structure decays and modules become entangled. | tool |
Maturity · 12 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
D15 |
Churn × Complexity Hotspots | Files that change often and are also complex — the riskiest hotspots. | When this is weak, the riskiest files — those that are both complex and change often — are concentrated and unaddressed, so the same hotspots keep generating defects. | tool |
D16 |
Bus Factor | Whether knowledge is concentrated in too few people (the "bus factor"). | When this is weak, knowledge of the code is concentrated in too few people, so the project is exposed if a key person becomes unavailable (the "bus factor"). | tool |
D19 |
Documentation Quality | Whether the project's documentation is clear, complete, and useful. | When this is weak, the project's documentation is unclear or incomplete, so new people lean on the original authors instead of the documents to get up to speed. | LLM · advisory |
D20 |
ADR Quality | Whether architecture decisions are recorded well (context, decision, consequences). | When this is weak, the reasons behind key architecture decisions are not recorded, so future maintainers cannot tell why the system was built the way it was. | LLM · advisory |
D21 |
Naming Consistency | Whether names — types, methods, variables — are clear and consistent. | When this is weak, names for types, methods and variables are unclear or inconsistent, so the code is harder to read and small misunderstandings turn into bugs. | LLM · advisory |
D24 |
Comment Value | Whether comments are worth it — explaining WHY (valuable) rather than WHAT (redundant). | When this is weak, comments mostly restate what the code already says instead of explaining why, so they add clutter without helping the next reader. | LLM · advisory |
D25 |
ADR Conformance | Whether the code actually follows the decisions recorded in the project's ADRs. | When this is weak, the code does not actually follow the architecture decisions the project wrote down, so the documented design and the real system have drifted apart. | LLM · advisory |
D34 |
Knowledge Freshness | Whether anyone still has living knowledge of each file, or it has been orphaned — last understood long ago by someone now gone quiet. The sibling of the bus factor: D16 asks who owns it, D34 asks whether anyone still knows it. | tool | |
M1 |
Documentation (README)meta | Whether the repo and its projects have a README, and whether it's substantive and current. | When this is weak, the repository lacks a substantive, current README, so anyone picking up the project has no reliable starting point and onboarding is slower. | tool |
M2 |
Architecture documentationmeta | Whether key decisions (ADRs) and the high-level shape (C4/diagrams) are written down. | When this is weak, the key decisions and the high-level shape of the system are not written down, so its design lives only in people's heads and is lost when they leave. | tool |
M3 |
Folder & project structuremeta | Whether the repo is organised deliberately — src/test separation and consistent project naming. | When this is weak, the repository is not organised deliberately — source and tests are not cleanly separated and project naming is inconsistent — so it is harder to find your way around. | tool |
M4 |
Documentation accuracymeta | Whether the README actually describes the code that exists (LLM-judged, advisory). | When this is weak, the README no longer matches the code that actually exists, so the documentation actively misleads anyone who relies on it. | LLM · advisory |
Readiness · 24 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
D8 |
Code Coverage | How much of the code is actually exercised by tests. | When this is weak, little of the code is actually exercised by tests, so most defects are found by your users in production rather than by the test suite. | tool |
D9 |
Test Distribution | Whether the test suite has a healthy mix of unit / integration / end-to-end tests. | When this is weak, the test suite is lopsided — missing the right mix of unit, integration and end-to-end tests — so whole categories of failures go uncaught. | tool |
D10 |
Test Quality | Whether the tests truly assert behaviour rather than just running the code. | When this is weak, the tests run the code but do not really check its behaviour, so they can pass while the software is in fact broken — giving false confidence. | tool |
D11 |
Test Reliability | Whether the tests pass reliably, with no flakiness. | When this is weak, the tests do not pass reliably, so failures get ignored as "flaky" and a real regression can hide among the noise. | tool |
D12 |
Dependency Hygiene | Whether dependencies are current, secure, and not bloated. | When this is weak, the dependencies are out of date, insecure or bloated, so the project carries avoidable risk and is harder to keep current. | tool |
D13 |
Secret Scanning | Whether any secrets (keys, tokens, passwords) have leaked into the code. | When this is weak, secrets such as keys, tokens or passwords are present in the code, where anyone with access to it can read and misuse them. | tool |
D14 |
License Compliance | Whether the licenses of third-party packages are compatible with your policy. | When this is weak, third-party package licenses have not been checked against your policy, so you may be using components on terms your organisation cannot accept. | tool |
ED5 |
Idempotencymeta | Whether retry-prone mutations (command handlers + message/event consumers) are idempotent so an at-least-once redelivery or client retry doesn't double-apply the effect — heuristic at-risk detection confirmed by language model, advisory. | LLM · advisory | |
P1 |
CI/CD gatesmeta | Whether an automated pipeline builds and tests every change. | When this is weak, there is no automated pipeline building and testing every change, so broken code can reach the main branch and problems are caught late, if at all. | tool |
P2 |
Observabilitymeta | Whether the code is diagnosable in production — structured logging, tracing/metrics, health checks. | When this is weak, the running system is hard to diagnose — no structured logging, tracing or health checks — so when something breaks in production you are flying blind. | tool |
P3 |
Security & performance toolingmeta | Whether SAST, secret/dependency scanning and performance benchmarking are wired in (presence, not runtime). | When this is weak, security and performance tooling — SAST, secret/dependency scanning, benchmarks — is not wired in, so the project has no automated guard against these risks. | tool |
P4 |
Deployment & Rollbackmeta | Whether releases are automated and safely reversible (probes, rolling updates, approval gates) — from manifests/pipeline files, not the live environment. | When this is weak, releases are not automated or safely reversible, so every deployment is a manual, error-prone event and rolling back a bad release is slow and risky. | tool |
P5 |
DR & Backupmeta | Whether disaster recovery is planned and codified — backups, geo-recovery, RTO/RPO, persistence guarantees — from IaC + container manifests + docs, never the live cloud. | When this is weak, there is no planned, codified disaster recovery — no backups, no recovery targets — so a serious failure could mean prolonged downtime or permanent data loss. | tool |
P6 |
Release Hygienemeta | Whether releases are traceable — a maintained changelog and explicit version stamping. | When this is weak, releases are not traceable — no maintained changelog or version stamping — so it is hard to tell which version is running or what changed between releases. | tool |
P7 |
Outbound HTTP resiliencemeta | Whether outbound HTTP calls are wrapped in resilience (retry/timeout/circuit-breaker) so a failing dependency doesn't cascade. | When this is weak, outbound calls to other services have no retry, timeout or circuit-breaker, so a single slow or failing dependency can cascade and take the whole system down. | tool |
P8 |
Schema migrationsmeta | Whether EF Core schema changes go through versioned migrations rather than the un-evolvable EnsureCreated(). | When this is weak, database schema changes are not handled through versioned migrations, so updating an existing database safely becomes a manual, risky operation. | tool |
P9 |
Domain vs controller coveragemeta | Whether test coverage concentrates on the domain (business rules) rather than the trivial web/controller layer — a focus check a generic tool can't make. | When this is weak, the tests focus on the trivial web layer instead of the business rules, so the parts that matter most to your operation are the least verified. | tool |
P10 |
Library API & versioningmeta | For a library: a deliberate (small) public API surface and explicit semantic versioning so consumers can depend on it safely. | When this is weak, a library exposes a large, undisciplined public surface with no clear versioning, so consumers cannot depend on it without risking breakage on every update. | tool |
P11 |
BDD / executable specsmeta | Whether behaviour is captured as executable Gherkin specifications (a plus for shared understanding) — only assessed when a BDD framework is present. | When this is weak, the project does not capture behaviour as executable specifications, so the shared, business-readable description of how the system should behave is missing. | tool |
P12 |
CI test-gate honestymeta | Whether the CI gate executes the test inventory it appears to have: excluded suites, skipped tests, and coverage collected without a threshold. | tool | |
R4 |
Test Coveragemeta | Static test reachability (D-386): the share of production files reachable from any test via the import graph — measured without running anything. | When this is weak, large parts of the frontend are not reachable from any test, so changes there can break behaviour with nothing to catch it. | tool |
R5 |
Dependency Freshnessmeta | How outdated the npm dependencies are (a maturity signal). JS/npm CVEs are scored separately in D33 (JS/npm Dependency Vulnerabilities). | When this is weak, the npm dependencies are well out of date, so the project drifts further from current, supported versions and upgrades grow harder over time. | tool |
R6 |
Toolingmeta | Whether the project wires up test, lint and typecheck — detected from each package.json script's COMMAND (eslint / tsc / vitest / jest / playwright), not just its name, and corroborated against CI-workflow invocations so a tool run only in CI still counts. | When this is weak, the frontend has no wired-up test, lint and typecheck scripts, so quality checks are not part of the normal workflow and are easily skipped. | tool |
R8 |
Dependency Hygienemeta | npm dependency truthfulness (D-386): unused dependencies, imports not declared anywhere, and type-/test-only packages shipped as production deps. | When this is weak, the npm dependencies are not truthful — unused packages, undeclared imports, dev-only packages shipped as production — so the dependency list cannot be trusted and builds are fragile. | tool |
Security · 21 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
D28 |
Secrets (history) | Whether any secrets were ever committed — scanned across the full git history, not just now. | When this is weak, secrets were committed somewhere in the project's history, so even if removed today they remain readable to anyone who can clone the repository. | tool |
D29 |
Static Analysis (SAST) | Real static-analysis (SAST) findings — likely security bugs in the code, any language. | When this is weak, automated static analysis finds likely security bugs in the code, meaning real, exploitable weaknesses are present in the delivery. | tool |
D30 |
Dependency Vulnerabilities | Whether any dependencies have known published vulnerabilities (CVEs), direct or transitive. | When this is weak, dependencies carry known published vulnerabilities (CVEs), so the delivery ships with publicly documented weaknesses an attacker can look up and exploit. | tool |
D31 |
IaC & Container Security | Whether Dockerfiles / Terraform / Kubernetes config follow security best practices. | When this is weak, the Docker, Terraform or Kubernetes configuration does not follow security best practices, so the infrastructure itself is misconfigured and exposed. | tool |
D32 |
Data Compliance (PII/GDPR) | Likely personal-data (PII / GDPR) handling concerns — logging or storing data without safeguards. | When this is weak, the code likely handles personal data without proper safeguards — logging or storing it unprotected — exposing you to GDPR and privacy risk. | tool |
D33 |
JS/npm Dependency Vulnerabilities | Whether JavaScript/npm dependencies have known published vulnerabilities (CVEs) — the npm ecosystem's biggest risk. | When this is weak, JavaScript/npm dependencies carry known published vulnerabilities (CVEs) — the npm ecosystem's biggest risk — so the frontend ships with documented, exploitable weaknesses. | tool |
D36 |
Supply-chain Provenance & Signing | Whether the build pipeline provides supply-chain integrity — generated provenance/attestation, signed artifacts (cosign/sigstore), an SBOM, and pinned build actions. Presence of the configuration, not a runtime guarantee. | When this is weak, the build pipeline lacks supply-chain integrity — no provenance, signing or SBOM, or unpinned actions — so a consumer can't verify how the artifact was built or whether it was tampered with. | tool |
D37 |
Vulnerability-disclosure Policy | Whether the repository publishes a coordinated-vulnerability-disclosure policy (SECURITY.md or security.txt) with a reporting contact, so finders know how to report a vulnerability. Presence of a policy file with a contact, not whether the policy is adequate or honoured. | When this is weak, there is no published vulnerability-disclosure policy (no SECURITY.md or security.txt with a reporting contact), so a researcher who finds a flaw has no documented way to report it to you. | tool |
D38 |
OSV Dependency Vulnerabilities | Whether dependencies have known published vulnerabilities (CVEs) per the OSV database — npm and other lockfile ecosystems, parsed natively. Complements D33 (npm via trivy) and D30 (.NET via dotnet). | tool | |
D40 |
Network Egress Confinement | Whether Kubernetes workloads restrict network EGRESS with a NetworkPolicy (or Cilium policy), limiting where a compromised pod can send data or reach a command-and-control server. Presence of committed egress-restricting policy, not runtime enforcement. | tool | |
D41 |
Kernel & Syscall Confinement | Whether Kubernetes workloads confine the kernel boundary — a seccomp profile (RuntimeDefault/Localhost) plus an AppArmor/SELinux mandatory-access-control layer — shrinking the syscall attack surface a container escape would use. Presence of committed confinement config, not runtime enforcement. | tool | |
D42 |
Runtime Threat Enforcement | Whether the Kubernetes deployment wires runtime threat enforcement — a detection engine (Tetragon/Falco) and/or an admission-control policy gate (Kyverno / OPA Gatekeeper / PodSecurity). Presence of committed policy, not a runtime guarantee. | tool | |
C1 |
Data Protectionmeta | Whether sensitive data is encrypted at rest and in transit and keys are vaulted. | When this is weak, sensitive data is not consistently encrypted at rest and in transit with keys properly vaulted, so that data is more exposed if the system is breached. | tool |
C2 |
Access Controlsmeta | Whether access is authorized by default — [Authorize]/policies or imperative guard methods (throw-on-violation) called from handlers. | When this is weak, access is not authorised by default — endpoints lack proper role and policy enforcement — so data or actions may be reachable by people who should not have them. | tool |
C3 |
Audit Trailmeta | Whether changes to sensitive data are recorded (who, what, when) for compliance + incident response. | When this is weak, changes to sensitive data are not recorded, so you cannot tell who changed what and when — undermining compliance and incident response. | tool |
C4 |
Data Retentionmeta | Whether data has a defined lifetime — retention periods, TTLs, cleanup jobs (storage limitation). | When this is weak, data has no defined lifetime — no retention periods or cleanup — so personal and other data accumulates indefinitely, contrary to storage-limitation requirements. | tool |
C5 |
Data-Subject Rightsmeta | Whether GDPR data-subject requests are supported in code — erasure, export/portability, consent. | When this is weak, GDPR data-subject requests are not supported in code — no erasure, export or consent handling — so meeting a lawful request becomes a manual, risky scramble. | tool |
LA1 |
Personal-Data Handling (GDPR)meta | LLM-confirmed personal-data handling surface — fields that are genuine personal data about a real person (not fiction/test/config), surfaced for the GDPR Art. 25/32 self-assessment. Advisory. | When this is weak, the code handles personal data the team hasn't yet confirmed is minimised, retention-limited and protected — a GDPR Art. 25/32 exposure flagged by AI for a human to review. | LLM · advisory |
LA3 |
Vulnerability-Disclosure Policymeta | LLM-judged whether a SECURITY.md / security.txt is a real coordinated vulnerability-disclosure policy (contact + how to report + handling), not just a stub. Advisory. | When this is weak, there is no real coordinated vulnerability-disclosure policy (a security contact and a reporting process), so a researcher who finds a flaw has no safe way to report it (CRA/ISO), as judged by AI. | LLM · advisory |
LA4 |
Dev/Test/Prod Separationmeta | LLM-judged whether configuration separates development/test/production (distinct per-environment settings) rather than commingling them. Advisory. | When this is weak, development, test and production may share configuration and secrets rather than being separated, raising the risk that a test setting or credential reaches production (ISO A.8.31), as judged by AI. | LLM · advisory |
S1 |
Web-Security Posturemeta | Transport security, security headers, secure cookies, input validation, middleware order and crypto hygiene (presence, not runtime). | When this is weak, the web application lacks basic protections — transport security, security headers, secure cookies, input validation — leaving it open to common web attacks. | tool |
Domain Modelling · 8 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
DM1 |
Aggregate boundariesmeta | Whether aggregates reference each other by identity (id) rather than by direct object reference — the core DDD consistency-boundary rule. | When this is weak, the parts of the domain that must stay consistent reference each other directly instead of by identity, so the rules that keep your data correct are easier to break. | tool |
DM2 |
Strongly-typed idsmeta | How much of the domain uses strongly-typed ids vs raw Guid/string/int — adoption curve, not all-or-nothing. | When this is weak, much of the domain uses raw ids (plain strings, numbers, GUIDs) instead of strongly-typed ones, so it is easy to pass the wrong id and corrupt data without the compiler noticing. | tool |
DM3 |
Integration-event couplingmeta | Whether cross-context integration events stay loosely coupled — no producer-owned enums/domain types leaking to consumers. Shared-kernel/contracts types are allowed. | When this is weak, cross-context integration events leak internal domain types to their consumers, so independent parts of the system become tightly coupled and harder to change apart. | tool |
DM4 |
Rich vs anemic modelmeta | Whether aggregates/entities carry the behaviour that protects their invariants, rather than being data bags driven by external services. | When this is weak, the domain objects are little more than data bags whose rules live in external services, so the business rules that protect your data are scattered and easy to bypass. | tool |
DM5 |
Encapsulated statemeta | Whether entities protect their state (private/init-only setters) instead of exposing public setters that bypass invariants. Softened when a rehydration framework (Marten/EF) is present. | When this is weak, domain objects expose their internal state through public setters, so other code can change them in ways that skip the rules meant to keep them valid. | tool |
DM6 |
Domain ↔ infrastructure boundarymeta | Whether the domain layer stays free of infrastructure dependencies (EF/Marten/HTTP/ASP.NET) — the clean-architecture dependency rule. | When this is weak, the core business logic depends directly on technical infrastructure (database, HTTP, framework), so the rules at the heart of your system are hard to test and tied to specific technology. | tool |
DM7 |
Repository granularitymeta | Whether repositories are per aggregate root (not per child entity) so the root's invariants can't be bypassed. | When this is weak, data access is not organised around the natural consistency boundaries, so the rules that protect your most important objects can be bypassed. | tool |
DM8 |
Value-object opportunitiesmeta | Whether clusters of primitives that travel together (a missing value object) are extracted — a low-weight suggestion, LLM-confirmed when configured. | When this is weak, groups of values that belong together are passed around as loose primitives, so the same validation has to be repeated everywhere and is easy to get wrong. | LLM · advisory |
Event-Driven · 4 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
ED1 |
Handler temporal couplingmeta | Whether event handlers stay asynchronous (no blocking remote HTTP/gRPC calls awaited inside a handler). | When this is weak, event handlers block on remote calls instead of staying asynchronous, so one slow downstream service can stall the whole flow of events. | tool |
ED2 |
Event/command shapemeta | Whether commands have a single handler (one owner of the decision) and fan-out is modelled with events. | When this is weak, commands have several competing handlers and fan-out is not modelled with events, so it is unclear who actually owns each decision and behaviour becomes unpredictable. | tool |
ED3 |
Event namingmeta | Whether events are named in the past tense (a clarity nudge — low weight). | When this is weak, events are not named in the past tense, a small clarity issue that makes the flow of the system slightly harder to read at a glance. | tool |
ED4 |
Outbox / dual-writemeta | Whether state changes and message publishes are atomic (a transactional outbox) rather than a crash-unsafe dual write. | When this is weak, saving state and publishing a message are not atomic, so a crash at the wrong moment can leave the system having done one without the other — silently losing or duplicating work. | tool |
Event Sourcing · 3 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
ES1 |
Fold determinismmeta | Whether Apply/When folds reconstruct state purely from the event (no DateTime.Now, Guid.NewGuid, Random or IO) so replay is reproducible. | When this is weak, the logic that rebuilds state from events is not deterministic, so replaying the same history can produce different results — undermining the audit trail's trustworthiness. | tool |
ES2 |
Immutable eventsmeta | Whether persisted events are immutable facts (init-only/readonly) — a settable event member lets stored history be rewritten. | When this is weak, stored events can be modified after the fact, so the historical record is no longer a trustworthy account of what actually happened. | tool |
ES3 |
PII in the event storemeta | Whether the append-only event log avoids un-erasable personal data (or has a crypto-shredding strategy) — a GDPR right-to-erasure risk. | When this is weak, personal data is written into the append-only event log with no way to erase it, creating a direct conflict with the GDPR right to be forgotten. | LLM · advisory |
Accessibility · 10 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
AC1 |
Text alternativesmeta | Whether non-text content carries a text alternative — img/area/input[type=image] have alt, a meaningful svg has a title or aria-label, video has a captions track, and object/embed/canvas have a name or fallback content. Static markup readiness, not a WCAG conformance claim. | tool | |
AC2 |
Forms & labelsmeta | Whether form controls have a programmatic label (an associated label, aria-label or aria-labelledby), buttons have text, links have an accessible name, fieldsets have a non-empty legend, known UI-library field components carry a label prop, and a placeholder isn't used as the only label. Static markup readiness, not a WCAG conformance claim. | tool | |
AC3 |
Page structuremeta | Whether pages declare a language (well-formed BCP-47) and a non-empty title, expose exactly one main landmark and a sane heading order with non-empty headings, keep zoom enabled, title their iframes, give data tables header cells, and avoid meta-refresh. Static markup readiness, not a WCAG conformance claim. | tool | |
AC4 |
Keyboard semanticsmeta | Whether interactive behaviour is keyboard-reachable — no click handler on a non-interactive element lacking a role, tabindex and key handler, no positive tabindex, no href-less anchor, no placeholder-href (#/javascript) link acting as a button. Static markup readiness, not a WCAG conformance claim. | tool | |
AC5 |
ARIA correctnessmeta | Whether ARIA is used correctly — valid non-abstract roles, the ARIA state a role requires, valid (non-misspelled) aria-* attribute names, in-enum values for token-typed aria-* attributes, and no aria-hidden on (or wrapping) a focusable element. Static markup readiness, not a WCAG conformance claim. | tool | |
AC6 |
Visual & motion safetymeta | Whether focus outlines aren't removed without a replacement, motion respects prefers-reduced-motion, and literal CSS colour pairs meet contrast — PARTIAL: inline styles, in-repo <style> blocks, in-repo .css files, var() tokens, Tailwind neutral utilities and CSS-in-JS literals are read (hex/rgb/hsl/named), never computed/runtime/external-CDN colour. Static markup readiness, not a WCAG conformance claim. | tool | |
AC7 |
A11y enforcementmeta | Whether accessibility is ENFORCED in the toolchain — an a11y linter (eslint-plugin-jsx-a11y / vuejs-accessibility) configured, and axe/pa11y/Lighthouse wired into tests or CI — on the Documented→Verified→Prevented ladder. | tool | |
LA2 |
Alt-Text Quality (WCAG 1.1.1)meta | LLM-judged quality of image alt text — whether each alt is a meaningful equivalent rather than a filename, generic word or placeholder. Advisory; complements the deterministic 'alt present?' check. | When this is weak, images carry alt text that isn't a meaningful equivalent — filenames or generic words — so screen-reader users don't get the information the image conveys (WCAG 1.1.1), as judged by AI. | LLM · advisory |
LA5 |
Link & Button Text Quality (WCAG 2.4.4)meta | LLM-judged descriptiveness of link/button text — whether each conveys its purpose out of context rather than a vague 'click here'/'read more'. Advisory; complements the deterministic 'has a name?' check. | LLM · advisory | |
LA6 |
Heading & Label Text Quality (WCAG 2.4.6)meta | LLM-judged descriptiveness of heading/label text — whether each meaningfully describes its section or field rather than a placeholder ('Heading', 'Untitled', 'Label'). Advisory. | LLM · advisory |
Performance · 3 dimensions
| ID | Dimension | What it measures | Why it matters | Evaluator |
|---|---|---|---|---|
PF1 |
Benchmark disciplinemeta | Whether the library protects its performance with benchmarks — a BenchmarkDotNet suite, an allocation MemoryDiagnoser, and (ideally) a CI gate. Presence is credited as a bonus, never a deduction. | tool | |
PF2 |
Allocation hygienemeta | Whether the code is written to minimise allocations so it doesn't pressure its host's GC — Span/Memory, pooling (ArrayPool/ObjectPool), stackalloc, ValueTask, value-type structs and buffer writers. Reward-only: credited where present, never penalised where a simpler style is fine. | tool | |
PF3 |
Async & latency hygienemeta | Whether asynchronous code keeps its host responsive — a library awaits with ConfigureAwait(false) (so it never captures and stalls the host's context) and avoids sync-over-async blocking (.Wait()/.GetAwaiter().GetResult()) that wastes threads and risks deadlock. | tool |
No dimensions match that filter.