# taxonomy/vocabulary.project.taxonomy.md

> 203 lines of code and 0 definitions.

Tree: Coordination tree
Language: markdown
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-taxonomy-vocabulary-project-taxonomy-md
Source text: https://banes-lab.com/assets/sources/source.d9230b6991fc15e7387fd4ade72d08614a852234066ebf7fc1e75ff9cd59c321.generated.txt

## Source

```markdown
---
name: vocabulary
summary: The closed concern vocabulary this package draws from. Adding a word is a deliberate SSOT edit, never a convenience.
type: taxonomy
concern: governance
status: current
---

# Concern vocabulary

The raw word list. The rules that turn it into a deterministic standard live in
`placement.project.taxonomy.md` — read that first; this file is the closed vocabulary it draws from.

The machine-readable form is `taxonomy.config.ts`. That file is authoritative for the gate; this one
is authoritative for a reader. They are cross-checked — **a tag in one and not the other is a bug in
whichever drifted.**

**The SSOT holds data, not reasoning.** It carries the declarations a rule reads. Every rule _about_
those declarations lives here, because a rule written into a config is a document wearing a schema
and no code ever reads it.

## Scope

The concern set covers the files this package authors: contracts, rules, models, processing stages,
reports, entry points and templates. A family that classifies nothing is left out, because unused
words make the real set harder to search. A host that authors a new kind of file adds its family by an
edit to `taxonomy.config.ts`, following the steps under _Adding a word is the last resort_.

## How a word is read — position, not membership

Resolution is **positional, not lexical**. The concern is the last dot-segment before the extension,
the subject is the first, the variant sits between. A word is read by the slot it lands in, never by
which array declares it.

- **concern slot** — must be a declared concern tag. Closed set.
- **subject slot** — any declared subject **or any concern tag**, because a file may be about a class
  of things: a registry of rules, a validator of schemas.
- **variant slot** — drawn from `variants` ∪ `subjects`. A declared word like every other slot.
- **subject must not equal concern.** `config.config.ts` is degenerate — the subject carries no
  information.

The legal subject set is `subjects` ∪ every concern tag, so `subjects` lists only domain nouns that
are **not already concerns**, and the config's type assertions fail on a redundant redeclaration.

A concern word in the subject slot is legal only when the file's target _is_ that class of thing.
`rule.registry.ts` is a registry of rules. That does not license `rule.cache.ts` meaning "a cache
that internally holds rules" — that is a variant wearing a subject's clothes.

**A hyphen inside a slot is spelling; the dot is the only separator.** Kebab-case throughout. A
folder carries one word and never a dot.

## Adding a word is the last resort

**An undeclared word is not a license to add it.** Work the steps in order.

1. **Pick an existing word.** The vocabulary is small on purpose. Most undeclared words are a
   synonym, an abbreviation, or a process-name for something already declared.
2. **Reason the word.** Subject = a noun naming a thing the system HAS. Variant = a noun that
   NARROWS a subject. Concern = a role a FILE PLAYS. Container = a grouping of modules. State which
   and why from the word's own meaning — never from where the file currently sits.
3. **Apply the is-a test.** Does a file IS-A this word? Then it is a role → `concerns`. Does the
   system merely HAS-A it? Then it is a domain noun → `subjects`.
4. **If it fails the reasoning, the filename is wrong.** Rename the file. Do not bend the vocabulary
   to fit a bad name.
5. **If the file has two roles, the file is wrong.** Split it. The ambiguity is the finding.
6. **Only if it survives, propose it.** Approved after the reasoning is shown. Never silently, never
   in bulk, never to make a check pass.

### Reject on sight

- **nominalised verbs and processes** — names what the system DOES, not what it HAS
- **adjectives** — no slot takes them
- **plurals as subjects** — a subject is singular
- **abbreviations duplicating a real word**
- **grouping labels** — `misc`, `common`, `shared`, `core`, `util`. Names a bucket, not a thing. This
  governs the subject slot; a grouping is exactly what a container is for. `base` is exempt, below.
- **measurements and properties** — data, not files
- **generic catch-alls** — `util`, `helper`, `handler`, `manager`, `thing`. They exclude nothing, so
  they classify nothing.
- **instance ids** — registry entries are content, not vocabulary
- **a word overlapping an existing entry**
- **a compound that swallowed a concern** — the tail is the concern, the head is the subject

> `util`, `helper` and `handler` are not declared as concerns, because each is a generic catch-all
> under the list above. A file reaching for `handler` takes `processor`, `coordinator` or
> `service` by what it actually does.

**`manager` is not a concern.** It names a stature, not a role, which is why it attaches to lifecycle
owners, caches, registries and coordinators alike. It resolves to `coordinator` (owns a lifecycle,
drives collaborators) or `service` (stateful capability). A file that cannot choose is doing both —
split it.

**`base` is the one sanctioned generic subject.** It means the file is generic over its subject and
would be byte-identical in any domain. Both tests must hold: generic over its type parameters, and
naming no domain noun anywhere in its source. A file mentioning any domain noun takes that noun
instead. `base` is not a home for files that resist classification.

## The concerns

Each tag carries exactly one canonical layer. The spine is
`domain > application > processing > runtime > infrastructure > operations > product`, ordered
domain-ward, and used **only as a tie-break**. It is the classification axis — what kind of thing a
file is — and says nothing about who may depend on whom.

### Structure and contract — infrastructure / domain

| folder           | file tag          | layer          |
| ---------------- | ----------------- | -------------- |
| `contracts`      | `.contract.`      | infrastructure |
| `specifications` | `.specification.` | domain         |
| `schemas`        | `.schemas.`       | infrastructure |
| `types`          | `.types.`         | infrastructure |
| `constants`      | `.constants.`     | infrastructure |
| `strings`        | `.strings.`       | infrastructure |
| `predicates`     | `.predicate.`     | infrastructure |
| `guards`         | `.guard.`         | infrastructure |

### Dependency and extension — infrastructure

| folder       | file tag     |
| ------------ | ------------ |
| `registries` | `.registry.` |
| `resolvers`  | `.resolver.` |
| `loaders`    | `.loader.`   |
| `factories`  | `.factory.`  |
| `manifests`  | `.manifest.` |
| `bindings`   | `.binding.`  |
| `plugins`    | `.plugin.`   |
| `config`     | `.config.`   |
| `caches`     | `.cache.`    |

### Domain modeling — domain

| folder        | file tag       |
| ------------- | -------------- |
| `rules`       | `.rule.`       |
| `policies`    | `.policy.`     |
| `models`      | `.model.`      |
| `invariants`  | `.invariant.`  |
| `constraints` | `.constraint.` |
| `records`     | `.record.`     |
| `collections` | `.collection.` |
| `snapshots`   | `.snapshot.`   |

### Application services — application

| folder          | file tag         |
| --------------- | ---------------- |
| `coordinators`  | `.coordinator.`  |
| `orchestrators` | `.orchestrator.` |
| `services`      | `.service.`      |
| `stages`        | `.stage.`        |
| `steps`         | `.step.`         |

### Serialization and processing — processing

| folder         | file tag        |
| -------------- | --------------- |
| `readers`      | `.reader.`      |
| `writers`      | `.writer.`      |
| `transformers` | `.transformer.` |
| `normalizers`  | `.normalizer.`  |
| `formatters`   | `.formatter.`   |
| `pipelines`    | `.pipeline.`    |
| `processors`   | `.processor.`   |
| `filters`      | `.filter.`      |
| `validators`   | `.validator.`   |
| `matchers`     | `.matcher.`     |
| `comparators`  | `.comparator.`  |
| `iterators`    | `.iterator.`    |
| `generators`   | `.generator.`   |
| `analyzers`    | `.analyzer.`    |
| `inspectors`   | `.inspector.`   |

### Failure and reporting — operations

| folder      | file tag     |
| ----------- | ------------ |
| `errors`    | `.error.`    |
| `results`   | `.result.`   |
| `reporters` | `.reporter.` |
| `reports`   | `.report.`   |
| `taxonomy`  | `.taxonomy.` |

### Runtime and product

| folder        | file tag       | layer   |
| ------------- | -------------- | ------- |
| `entrypoints` | `.entrypoint.` | runtime |
| `runners`     | `.runner.`     | product |
| `fixtures`    | `.fixture.`    | product |
| `references`  | `.reference.`  | product |
| `templates`   | `.template.`   | product |

### Plurality

| form                                       | folder   | file tag   | example                                  |
| ------------------------------------------ | -------- | ---------- | ---------------------------------------- |
| collection — one file defines many members | plural   | **plural** | `schemas/` ⇒ `record.schemas.ts`         |
| single-unit — one instance per file        | plural   | singular   | `validators/` ⇒ `placement.validator.ts` |
| mass / uncountable                         | singular | singular   | `config/`, `taxonomy/`                   |

Collection concerns here: `schemas`, `types`, `constants`, `strings`. Mass concerns: `config`, `taxonomy`.
Everything else is single-unit.

## Covered by a meta concern — do not add

The rejected list is the useful half of a closed vocabulary. Each entry reads like a deployment
concern and is already an agnostic one.

| tempting tag                   | classify as                     | why                                        |
| ------------------------------ | ------------------------------- | ------------------------------------------ |
| `checker`, `linter`            | `validator`                     | it decides valid or invalid                |
| `scanner`                      | `analyzer` or `inspector`       | it reads and derives, it does not judge    |
| `parser`, `lexer`, `tokenizer` | `reader`                        | it turns a format into structure           |
| `fixer`, `healer`, `repairer`  | `transformer`                   | it maps input state to output state        |
| `walker`, `crawler`            | `iterator`                      | it yields members of a set                 |
| `gate`                         | `predicate` or `validator`      | a gate is a decision, not a thing          |
| `index`                        | `registry`                      | a lookup structure is a registry           |
| `helper`, `util`               | none — the file has a real role | find it and name it                        |
| `manager`                      | `coordinator` or `service`      | split by what it actually does             |
| `handler`                      | `processor` or `coordinator`    | it names stature, not role                 |
| `doc`, `guide`, `note`         | `reference`                     | authored knowledge is a reference          |
| `digest`, `summary`            | `reference` or `rule`           | by whether it informs or obliges           |
| `checklist`, `plan`            | `specification`                 | it declares required end state             |
| `inventory`                    | `registry`                      | a named set of known members               |
| `changelog`                    | none — structurally exempt      | history has one home, outside the taxonomy |

`digest` deserves a line: it can mean a cryptographic hash or a rule summary. Declaring it would collide two meanings on one tag, so it is declared
neither way — a rule expansion is a `rule`, and a knowledge summary is a `reference`.

## The subjects

**The subject array is the one slot whose members are a project's own nouns**, so it is not listed
here: it lives in the configuration, where a host adds what it HAS and nothing else. A subject list
transcribed into prose is a second vocabulary that disagrees with the compiled one the first time
either moves — and the compiled one is the copy the assertions check.

What the array holds is decided by one rule and it is the same in every host: **a noun the host
actually has, excluding every word already a concern tag.** A word that names stature rather than
substance — a manager, a handler, a helper, a util — classifies nothing and is refused whatever the
host.

The array is closed. An undeclared word is an approved edit to the configuration, never a naming choice
made at authoring time, and the cross-slot assertions compiled beside it reject a subject that shadows a
concern tag before a single file is placed.

## The variants

`comms` · `project` · `protocol`

A variant is present only on a genuine collision within one folder, or to name a facet the subject
alone does not. No collision and no facet means one compound kebab subject and no variant.
```
