git:20260527.c1e80b1 to git:20260610.b0535dc
16 added, 12 removed. Audit A to A.
# core/dsl/model — directory guide
The model half of the projection machinery, symmetric with
`core/dsl/operation/oas/`. Files:
- - `ModelProjectionBase.ts` — runtime base class. Subclasses extend
- it. Carries `settings: ContentSettings<E>` (including
- `settings.variant`) and `generatorKey`. The `insertModel` /
- `insertNormalizedModel` wrappers accept an optional `variant` arg
- and forward it through `context`.
- - `toModelProjectionBase.ts` — factory. Builds a class with static
- `toIdentifier` / `toExportPath` / `toEnrichments` / `isSupported`
- / `id` / `type`. 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. `transform`,
+ - `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`.
No `isSupported` field; model entries filter inside `transform`.
- `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.
- `affirmDefinition` builds the call's `generatorKey` with variant
in the 3rd segment; the cache-key uniqueness invariant is
enforced here.
- `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.
- `ModelDriver.variants.test.ts` — Driver-level peer-variant guard
and the `generatorKey` collision check for variants-aware model
Projections.
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>