git:20260619.9ecf89a to git:20260914.6178b88

5 added, 0 removed. Audit A to A.

# core/dsl/model — directory guide
The model half of the projection machinery, symmetric with
`core/dsl/operation/oas/`. Files:
- `toModelProjectionBase.ts` — factory. Takes a
`base: LangSnippetConstructor` (a language package's snippet base,
pre-bound by the lang veneer — e.g. `toModelProjectionBase` from
`@skmtc/lang-typescript`) and builds a class on it carrying the
projection machinery (`settings`, `refName`, `generatorKey`
injection, `insertModel` / `insertNormalizedModel` with optional
`variant`) plus the statics `toIdentifier` / `toExportPath` /
`toEnrichments` / `isSupported` / `id` / `type` / the inherited
`lang`. Defines NO register — that's the veneer's. The constructor
reads `args.settings.variant` and threads it into the
`toModelGeneratorKey` call so the resulting Definition's
`generatorKey` carries the variant. Enrichment lookup walks
`enrichments.${id}.${refName}.${variant}`.
- `toModelEntry.ts` — pipeline-side factory; pure pipeline config (no
`lang` — the import graph declares the language). `transform`
(`({ context, refName, variant }) => void` — no accumulator),
`toPreviewModule`, and `toMappingModule` all receive `variant`.
Optional `isSupported` (symmetric with the operation entries):
wrapped to pre-parse the `{ subject, generator, stack }` enrichment
umbrella, then exposed on the built config (defaulted to
`() => true`). The predicate gets `{ context, refName, enrichments,
variant }` — no schema; resolve it via `context.resolveSchemaRefOnce`
when the gate needs it. The engine evaluates it per (refName, variant)
before `include`/`skip` and records `notSupported` on a `false`.
- `ModelDriver.ts` — the insertion lifecycle (compose
`ContentSettings`, look up via `findDefinition`, integrity-check
via `affirmDefinition`, register the Definition, register the
import). Variant-related entry points:
- Constructor takes a `variant: string` arg and stores it on the
instance.
- `assertPeerVariantExists` runs before `toModelContentSettings`
— throws if the caller asked for a non-`'main'` variant the peer
doesn't declare.
- `assertPeerSupported` runs next — probes the peer projection's
static `isSupported({ refName, context })` and throws if it
returns `false` (the model counterpart of the OAS-operation
peer-capability guard; a peer with no static is treated as
supporting everything).
- `affirmDefinition` builds the call's `generatorKey` with variant
in the 3rd segment; the cache-key uniqueness invariant is
enforced here.
+ - The constructor reads the caller's `options` off the call
+ (`readProjectionOptions`) and threads them into
+ `toModelContentSettings` (so `toIdentifierName` / `toExportPath`
+ receive them) and the projection constructor. See
+ `types/ProjectionOptions.ts`.
- `types.ts` — arg shapes. Every `To*Args` and `Transform*Args`
carries `variant: string`.
**Variants-aware vs unaware (mirrors the OAS-operation patterns):**
- *Unaware*: destructure `variant` in `toExportPath` (since the body
calls `this.toIdentifier({…, variant})`), ignore it in
`toIdentifier`. Engine still dispatches with `variant: 'main'` for
every refName.
- *Aware*: `toIdentifier` folds variant into the name via
`withVariant(base, variant)` from `@/helpers/withVariant.ts`.
`toExportPath` inherits the suffix through the
`this.toIdentifier({…, variant})` call.
**Cross-generator insertion**: callers compose with the peer's
`'main'` Definition by default — `context.insertModel(Peer, refName)`
defaults `variant` to `'main'`. Pass `{ variant }` explicitly only
when the peer is known to be variants-aware AND declares that
variant in its enrichment block.
Tests pinning model-variant invariants:
- `core/context/GenerateContext.model-variants.test.ts` — engine
fan-out, missing-`main` throw, per-variant skip/include matching,
and the `isSupported` capability gate (per-refName gating;
`isSupported` runs before `include`).
- `ModelDriver.variants.test.ts` — Driver-level peer-variant guard
and the `generatorKey` collision check for variants-aware model
Projections.
- `ModelDriver.test.ts` → "Peer support validation" — Driver probes
the peer's `isSupported` on `insertModel`.
Concept doc: `docs/concepts/variants.md`. Skill:
`docs/skills/skmtc-generator/SKILL.md`.
---
<claude-mem-context>
# Recent Activity
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
### May 11, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20455 | 7:03 PM | 🔄 | ModelDriver simplified using Identifier.toImport instead of manual import construction | ~577 |
| #20421 | 6:59 PM | 🔵 | EntityType already exists on Identifier and drives isType boolean conversion | ~569 |
| #20419 | " | 🔵 | isType flag implementation across core DSL import system | ~592 |
| #20418 | " | 🔵 | Current isType boolean implementation in Import DSL | ~522 |
### May 12, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20928 | 2:20 PM | 🔵 | Critical enrichment routing path discrepancy discovered in documentation | ~940 |
### May 13, 2026
| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #21201 | 11:04 AM | ✅ | Created comprehensive API reference documentation for entry factory functions | ~544 |
| #21156 | 8:10 AM | 🔵 | toPreviewModule confirmed active in entry factory APIs | ~488 |
</claude-mem-context>