Type to search pages and rules.

Browse pages

Record Identifiers

Every record carries one identifier naming its type, its home, and its own name. This page states the identifier grammar for each record type, the rules for choosing names, and how citations resolve, with wire codes kept stable for deployed clients. The Project Model states each type and its home; the checks here enforce the grammar.

Markdown6 rules

Stack: any Layer: records

Concepts#

Identifier Forms#

An identifier names its record type first, then the record name, with the owning home in between when the type has one. The model states the form each type uses, with one row per type and one example per row. A rule home is an aggregate name or a module name. A result or scenario home is a use-case name, and an event home is an aggregate name. A use-case name is unique across the project, so a result cites only that name; an aggregate name is unique across the project, so a rule cites only that name. Both follow litespec/core/model#keep-each-name-unique-in-the-product. A reaction, job, notification, and setting home is the module that owns it: reaction/spending.send-approver-reminder-on-expense-submitted is a reaction owned by the spending module. An integration event has no module home: integration-event/expense.reimbursed names the published set. A rule name keeps the negation its statement makes, as litespec/core/domain-model#keep-the-negation-word-in-the-rule-name requires. A journey step identifier is journey/<name>#<step-id>, and a derived generic result is result/<use-case>.forbidden or result/<use-case>.invalid-input; scenarios may point at derived results, which are never written as records.

Name Rules#

The name is the last segment of the identifier: submit-expense in use-case/spending.submit-expense. Every name follows these rules:

  • Write one to six lowercase words joined by hyphens.
  • Place digits inside a word; a name of digits alone breaks the rules.
  • Count the decision number as a word.
  • Let a person choose the name; no tool builds one by stripping words from a sentence.

Use case and aggregate names stay unique across the project under litespec/core/model#keep-each-name-unique-in-the-product.

Wire Codes#

A wire code is a value a client reads and branches on, such as a refusal code like spending.receipt-missing or an audit action code. Wire codes are not identifiers: they name no record, they keep one shape, and they stay unchanged once clients read them.

Resolution#

Resolution means every identifier citation names a record that exists. The model check fails an unresolved citation, so a citation points only at a record someone wrote.

Shared provisions keep their published litespec/<page>#<slug> form, as stated under provision identifiers.

Standards#

Follow the Identifier Form of Each Record Type#

rulerulecheckable
litespec/backend/identifiers#follow-the-identifier-form-of-each-record-type
Statement

A record identifier MUST follow the form the model states for its record type.

Why

A reader who meets use-case/spending.submit-expense knows it is a use case in the spending module without opening it. If two types shared one form, a citation needs its surrounding page to make sense, and search returns the wrong records.

Example

event/expense.submitted names an event of the expense aggregate.

Checkchecked by a tool

Checked bylitespec model check reports identifier-invalid for an identifier outside the form its type uses.

Marked checkable: the tool named here checks it.

Name Records with One to Six Words#

rulerulecheckable
litespec/backend/identifiers#name-records-with-one-to-six-words
Statement

A name MUST carry one to six lowercase hyphenated words.

Why

A short hyphenated name reads aloud in review and stays stable when the record's wording changes. A long name gets shortened differently at each citation, and the shortcuts drift into competing names for one record.

Example

decision/0001-receipt-threshold counts its number as one word.

Checkchecked by a tool

Checked bylitespec model check reports identifier-invalid for a name outside one to six lowercase hyphenated words.

Marked checkable: the tool named here checks it.

Use Every Identifier Once#

rulerulecheckable
litespec/backend/identifiers#use-every-identifier-once
Statement

A record identifier MUST name exactly one record.

Why

An identifier used twice names two records at once, so every citation of it points both ways. One use per identifier keeps each citation single-valued.

Example

Two records named use-case/spending.submit-expense leave the model check reporting the duplicate on the second record.

Checkchecked by a tool

Checked bylitespec model check reports identifier-duplicate for an identifier used twice.

Marked checkable: the tool named here checks it.

Keep Wire Codes Stable#

ruleruleguidance
litespec/backend/identifiers#keep-wire-codes-stable
Statement

A wire code MUST stay unchanged once clients read it.

Why

Wire codes travel to deployed clients, which branch on their exact values. Renaming a code that clients already read breaks every deployed reader that compares the old value, with no record the reader opens to learn the new one.

Checka reviewer answers

Reviewed forWhich wire codes in the contract break the values deployed clients branch on? Look at the wire codes beside the deployed clients.

Marked guidance: a reviewer answers this question.

Resolve Every Identifier Citation#

rulerulecheckable
litespec/backend/identifiers#resolve-every-identifier-citation
Statement

Every identifier citation MUST resolve to a written record.

Why

A citation is a promise that a record exists at the other end. A citation that names nothing sends the reader searching for a record nobody wrote, so the model check fails it.

Checkchecked by a tool

Checked bylitespec model check reports reference-unknown for a citation naming no written record.

Marked checkable: the tool named here checks it.

Cite Shared Provisions in Their Published Form#

rulerulecheckable
litespec/backend/identifiers#cite-shared-provisions-in-their-published-form
Statement

A shared provision citation MUST use its published identifier.

Why

A shared provision is cited across projects, so its identifier looks the same everywhere. The published litespec/<page>#<slug> form stays fixed, while project records use the type forms above.

Checkchecked by a tool

Checked bylitespec-maintain validate emits no ID_UNKNOWN_REFERENCE diagnostic.

Marked checkable: the tool named here checks it.

Conventions#

None.

Reference Example#

This informative example demonstrates litespec/backend/identifiers#follow-the-identifier-form-of-each-record-type and litespec/backend/identifiers#name-records-with-one-to-six-words.

Claimwick names one module, one aggregate, one rule, and one use case with its results. It also names a reaction, a notification, a setting, and an integration event.

Text
module/spending
aggregate/spending.expense
rule/expense.approver-is-not-submitter
use-case/spending.submit-expense
result/submit-expense.submitted
result/submit-expense.receipt-missing
reaction/spending.send-approver-reminder-on-expense-submitted
notification/spending.approval-reminder
setting/spending.receipt-threshold
integration-event/expense.reimbursed