# LS5009: Two Permissions Generate One Constant Name

## Intent

LS5009 is a compiler check that reports two permission records whose names generate the same constant, because the generator writes one constant per permission and cannot name two records with one name. This page states what the rule reports, where the error sits, and how to rename one of the permissions.

## Reference

### What the Rule Enforces

LS5009 enforces [Generate Runtime Values from the Records](https://litespec.dev/4.0.0/backend/dotnet/stack.md#generate-runtime-values-from-the-records) (`litespec/backend/dotnet/stack#generate-runtime-values-from-the-records`). It runs on Domain, Application, Infrastructure, and WebApi files, where the generator writes permission constants. Its category is `LiteSpec.Traceability`.

### What the Rule Reports

The generator names each permission constant by PascalCasing each kebab word of the permission name, so `permission/submit-expense` becomes `SubmitExpense`. The rule reports two permission records that produce one constant name, naming both, and the generator writes no permission constants until the clash is gone. The diagnostic has no source location, because the clash lives in the records.

### Failing Example

The permission list holds `permission/approve-level-2` and `permission/approve-level2`: both produce `ApproveLevel2`, because a word that starts with a digit has no capital to mark where it begins.

### Passing Example

The permission list holds `permission/approve-level-2` and `permission/approve-senior-level`: they produce `ApproveLevel2` and `ApproveSeniorLevel`.

### How to Fix

Rename one of the two permission records with `litespec rename`, so each name produces its own constant.

## Notes

### What the Rule Ignores

The rule does not run in test projects, where no permission or role constants are generated. On Domain, Application, Infrastructure, and WebApi files it covers role constants as well as permission constants. It stays silent when no `.litespec/project.json` is in reach, or when the docs root it names cannot be resolved; the CLI owns that configuration error.

### Severity

The rule is an error whenever it fires, because no constant can be generated for either record until the names differ. An `.editorconfig` entry for the rule id overrides it.
