# 2026-08-07 — Documentation tags and the type layout

Two passes over the source ahead of the 1.0.0 tag, both structural rather than behavioural. No exported symbol changed:
`lib/index.d.ts` carries the same 42 names before and after.

## Kind tags lead the block

Every doc block opened with its summary and carried its kind tag — `@class`, `@interface`, `@typedef`, `@module`,
`@constant`, `@function` — near the bottom, wedged between the last `@typeParam` and `@author`. The tag now comes first:

```ts
/**
 * @class
 *
 * A limiter that counts nothing.
 * ...
 */
```

54 files: the 52 under `src/`, plus `eslint.config.ts` and `rollup.config.ts`. Two blocks carried no kind tag at all —
`eslint.config.ts`'s default export and `rollup.config.ts`'s header — and were given `@constant` and `@module`.

The nine `test/**/*.spec.ts` files were left alone. Their top block documents a `describe()` call rather than an
exported declaration, and they sit outside both TypeDoc's entry points and ESLint's `files` list, so a tag there would
be inert.

Not enforced yet. The `documentation` plugin already carries `kind-tag-without-argument`, which checks that a kind tag
has no argument but not that one exists or leads the block. A fourth rule would close the gap; without one this holds
only as long as everyone remembers it, which is the same reason the other three exist.

## `types/` grouped into subdirectories

`types/capabilities/` had grown to 21 flat files, over half of them supporting shapes rather than capabilities. A
capability that owns shapes now gets a directory and takes them with it:

| Directory    | Contents                                                                                            |
| ------------ | --------------------------------------------------------------------------------------------------- |
| `object/`    | `ObjectStore`, `StoredObject`                                                                       |
| `request/`   | `RequestMetadata`, `RequestFacts`                                                                   |
| `sql/`       | `DataStore`, `SqlConnectionProvider`, `SqlCredentials`, `SqlStatement`, `SqlTarget`, `SqlWriteResult` |
| `telemetry/` | `TelemetrySink`, `RequestMetric`                                                                    |
| `vector/`    | `VectorIndex`, `VectorMatch`                                                                        |

`Capability` stays at the root, along with the five capabilities that are a single interface each — `CacheStore`,
`CoordinationStore`, `InferenceEngine`, `MessageQueue`, `RateLimiter`. A subject with one shape to its name does not
earn a directory.

Membership follows what a shape belongs to rather than what it is named, which is worth stating because two of the
placements read as wrong at a glance:

- **`RequestMetric` is under `telemetry/`**, not with the two types that share its prefix. `TelemetrySink` is the only
  thing that accepts one, and `request/` is otherwise about deciding which header may be believed.
- **`DataStore` is under `sql/`**. It is relational storage addressed with SQL and it imports `SqlStatement` and
  `SqlWriteResult`; leaving it flat would have split the SQL surface across two levels.

Under `types/` itself, `logging/` now holds `LogLevel` and `LogContext`. `LoggingSettings` stays at the root beside
`SecuritySettings` and `SystemConfiguration` — it is read through `resolve('logging')` like any other settings shape —
and is re-exported through `logging/index.ts`, so the grouping shows up in the barrel without splitting the
configuration shapes across two directories.

Each new directory has an `index.ts` with a `@module` block, matching `core/noop/`, and the parent barrels re-export
from the directory rather than reaching into files. `SqlTarget`'s relative link to `SqlCredentials` survived the move
untouched; `LogLevel`'s link to `Logger` needed a second `../`.

`SecuritySettings`, `SystemConfiguration`, and `Overrides` are the one cluster left flat. A `configuration/` directory
would finish the pattern and is deliberately deferred rather than forgotten.

## Verification

`npm run lint`, `npm run test:run` (85 specs, nine suites), `npm run build`, and `npm run build:docs` all clean. The
docs build is the one that matters for a move of this size: `typedoc.json` sets `treatWarningsAsErrors` alongside
`validation.invalidLink`, so a relative link left pointing at an old path fails the build rather than shipping as a
dead link.
