# The extension registry

An application may add data of its own to an OpenEik model: members in records and files in the model's folder. That is its **extension** ([Part I, 11](https://openeik.org/spec/0.4/foundations#11)). Everything an extension adds carries the application's **prefix**: members are named `<prefix>:<name>`, and files go in a folder `<prefix>/` at the top of the model's folder. This registry hands out the prefixes, so that no two applications use one name for two things, and no later version of OpenEik takes a name an application uses.

[`extensions.json`](https://openeik.org/registry/extensions.json) lists the registered prefixes (`prefixes`) and the names OpenEik keeps for itself (`reserved`). Its schema is [`schemas/registry/extensions.schema.json`](https://openeik.org/schemas/0.1/registry/extensions.schema.json). Unlike the schemas of a model's files, which keep the members they do not know (Part I, 10), it refuses them: the registry is edited by hand, and a misspelt member (`contacts` for `contact`) would otherwise pass unnoticed.

An application with the prefix `acme` writes, for example:

```json
{
  "acme:fireRating": "EI 60",
  "category": "wall",
  "id": "wall-south",
  …
}
```

and keeps its own files in `acme/`, such as `acme/frame-a/results/…` (Part VI, 8). A reader that knows nothing of `acme` keeps both and reads the model as its writer meant it (Part I, 11.2, rule 5).

## What a prefix looks like

2 to 32 lowercase ASCII letters, digits and hyphens: it starts with a letter, ends with a letter or a digit, has no two hyphens side by side, and is not a device name of a common operating system (`con`, `prn`, `aux`, `nul`, `com0` to `com9`, `lpt0` to `lpt9`), since it also names a folder. `acme`, `acme-energy` and `qto2` are prefixes; `Acme`, `acme_energy`, `-acme` and `a` are not. A folder at the top of a model's folder is a prefix's, or a reserved name's, whatever its letter case: `ACME/` is the folder of `acme`, and no application but `acme`'s writes into it (Part I, 11.3, rule 2).

## How to register

1. Check that the prefix you want is neither in `prefixes` nor in `reserved`.
2. Add your entry to `prefixes` in `extensions.json`, where its prefix falls in alphabetical order:

   ```json
   {
     "contact": "<an email address, or an https URL>",
     "description": "<the application, and what its extension adds>",
     "prefix": "<the prefix>",
     "registered": "<YYYY-MM-DD>",
     "registrant": "<who you are>",
     "url": "<optional: an https URL>"
   }
   ```

   | Member | |
   |---|---|
   | `prefix` | the prefix |
   | `registrant` | who you are: the organisation, the project or the person that makes the application, as you want to be named |
   | `contact` | how to reach whoever answers for the prefix: an email address or an `https` URL (an issue tracker, a contact page). A role address is better than a person's: the registry is public |
   | `description` | in a sentence or two (at most 280 characters), the application and what its extension adds |
   | `url` | optional: where the extension's members and files are described |
   | `registered` | the day your merge request is merged: give the day you open it, and the editor who merges it corrects it |

   Keep the file's form: members in alphabetical order, two spaces of indent, as the other entries are. `npm test` checks the file against its schema and against the rules below that a program can check (each prefix once and in order, none reserved, a withdrawal after the registration), and says what is wrong.
3. Open a merge request titled `Registry: <prefix>`, with your commit signed off ([`CONTRIBUTING.md`](https://gitlab.com/openeik/spec/-/blob/main/CONTRIBUTING.md), the DCO).
4. An editor checks it against the rules below and merges it, or says in the merge request what stands in the way. A registration needs no RFC, and costs nothing.

## The rules

1. **First come.** Merge requests for one prefix are taken in the order they were opened. The first that meets these rules gets the prefix.
2. **A contact and a description.** Every entry has a contact that reaches its registrant and a short description. Keep them current, by merge request.
3. **No squatting.** Register a name that is yours: your organisation's, your project's or your application's, or one plainly made from them. Do not register a name that belongs to someone else (another organisation's name or trademark, a product you do not make), a generic word for a kind of application or data (`analysis`, `cost`, `energy`), or a name to hold for later or to sell. Register one prefix, or one for each application you make. The editors refuse a registration that breaks this rule; one found to break it later is settled by the steward, in the open, after its contact has been heard ([`GOVERNANCE.md`](https://gitlab.com/openeik/spec/-/blob/main/GOVERNANCE.md)).
4. **Reserved names.** The names in `reserved` are OpenEik's: its own (`eik`, `openeik`, and every prefix that starts with `eik-` or `openeik-`, which `reserved` writes as `eik-*` and `openeik-*`) and the names of the folders at the top of a model's folder, now and planned. They cannot be registered. A new name is reserved only if no one has registered it.
5. **For good.** A prefix stands for one extension for good (Part I, 11.1, rule 4). Its registrant may hand it on with the application, to whoever carries on the same extension: the entry's `registrant` and `contact` change, and `notes` says so. A registrant may withdraw its prefix: the entry stays, with the day in `withdrawn`, and the prefix is never registered again, so that the models that carry it keep one meaning.
6. **Into the core.** When a version of OpenEik takes an extension into the core (Part I, 11.4), its entry's `notes` says what was taken, in which version and under which name. The prefix stays its registrant's.
7. **What a registration is not.** It reserves a name. It is no review and no endorsement of the extension, and gives its registrant no place in the specification ([`GOVERNANCE.md`](https://gitlab.com/openeik/spec/-/blob/main/GOVERNANCE.md), principle 1).

Questions go in an issue.
