# core/dsl — directory guide

The code-generation DSL. The vocabulary:

- **`SnippetBase`** — anonymous, embedded value. `toString()` is
  interpolated into a Projection's body.
- **`Projection`** — exportable named artifact. Three flavours, built by
  the projection-base factories (`toModelProjectionBase`,
  `toOasOperationProjectionBase`, `toGqlOperationProjectionBase`) on a
  language package's snippet base (`base: LangSnippetConstructor`) —
  generators consume them through the lang package's veneers (e.g.
  `toModelProjectionBase` from `@skmtc/lang-typescript`). Each carries
  `settings: ContentSettings<E>` (which includes `settings.variant`) and
  a `generatorKey`.
- **`Definition`** — the Driver-built wrapper around a Projection's
  value. Stamped with `generatorKey` for the integrity check.
- **`ContentSettings`** — the bundle of `(identifier, exportPath,
  enrichments, variant)` computed by the engine and threaded into
  every Projection.
- **`Identifier`** — neutral naming data: `name` + opaque per-language
  `kind` + `exported` + opaque `typeName`. Built via a language
  package's factories (`createVariable(name)` / `createType(name)`
  from `@skmtc/lang-typescript`); core never interprets `kind`.
  `EntityType` and the `Identifier.create*` statics are gone (F6).
- **`ImportBase` / `ReExportBase` / `CodeFileBase` / `DefinitionBase`** —
  the neutral contracts the language-blind engine speaks. Concrete
  classes (`TsFile`/`TsImport`/`TsReExport`/`TsDefinition`) live in
  `@skmtc/lang-typescript`; Drivers reach them through the `Lang`
  factories read ephemerally off the projection class's static
  (`projection.lang`, inherited from the lang snippet base). The legacy
  core `File`/`Import` classes are deleted. `context.register` is pure
  data (`ImportBase[]`/`ReExportBase[]`/`DefinitionBase[]` +
  `destinationPath`) and never creates files — callers pre-create
  through their language (the lang package's register function, the
  Drivers). Projection `register` (on the lang veneer) is own-file-only;
  `registerInto(path, args)` is the explicit cross-file path; snippet
  `register` (on `TsSnippet`) takes an explicit `destinationPath` and is
  **keyless** — `generatorKey` is optional attribution input only.
- **`GeneratorKey`** — branded pipe-delimited string. 4 segments for
  operations (`id|path|method|variant` OAS, `id|rootKind|fieldName|variant` GQL),
  3 for models (`id|refName|variant`), 1 for generator-only.
  Round-trip: `toOasOperationGeneratorKey` → `fromGeneratorKey`.
- **`Inserted<V, E>`** — Driver's return type from
  `context.insertOperation` / `insertModel`. Exposes `.settings`,
  `.definition`, `.toName()`.

Subdirectories:

- `model/` — `ModelProjectionBase` + factory + Driver. Models are
  variants-aware (symmetric with operations): the variant axis is
  threaded through `toIdentifier` / `toExportPath` / `toEnrichments`
  and folded into the 3-segment `ModelGeneratorKey`
  (`id|refName|variant`). Consumer enrichments key on
  `[generatorId][refName][variant]`; `'main'` must be present
  whenever any variant is declared (engine throws via
  `toVariantList`). Driver enforces the peer-variant guard via
  `assertPeerVariantExists`.
- `operation/oas/` — OAS operation flavour (Projection base,
  factory, entry, Driver). Variants-aware path.
- `operation/gql/` — GraphQL operation flavour. Same shape; `acc`
  threading is the only meaningful difference.

Concept doc: `docs/concepts/projections-and-snippets.md`. Variants
concept: `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 |
|----|------|---|-------|------|
| #20495 | 7:09 PM | 🟣 | Identifier.toImport() method implemented with comprehensive test coverage | ~587 |
| #20494 | " | 🔵 | Identifier test coverage examined before adding toImport method tests | ~577 |
| #20489 | 7:07 PM | 🔄 | Completed Import.test.ts migration removing all EntityType instance references | ~529 |
| #20488 | " | 🔄 | Final typeMarker() call replaced with raw 'type' string in Import test | ~519 |
| #20487 | " | 🔄 | Migrated statement-level import type test to use literal discriminator | ~423 |
| #20486 | " | 🔄 | Import tests finalized with string discriminator fixtures replacing EntityType | ~599 |
| #20485 | " | 🔄 | Import.test.ts removed EntityType import and typeMarker helper | ~533 |
| #20484 | " | 🔄 | Updated Identifier.toImport to return EntityTypeValue literal instead of EntityType instance | ~566 |
| #20483 | " | 🔄 | ImportName.toString() updated for string discriminator comparison | ~630 |
| #20482 | 7:06 PM | 🔄 | ImportName.type field documentation updated for EntityTypeValue simplification | ~596 |
| #20481 | " | 🔄 | Updated tagImportNameArg discriminator to use EntityTypeValue type guard instead of instanceof | ~498 |
| #20480 | " | 🔄 | Import API simplified from EntityType instances to string discriminators | ~537 |
| #20479 | " | 🔄 | ImportName.type simplified from EntityType instance to EntityTypeValue discriminator | ~606 |
| #20478 | " | 🔄 | Simplified ImportNameArg type field from EntityType instance to literal discriminator | ~489 |
| #20477 | " | 🔄 | Import.ts switched from EntityType class import to EntityTypeValue type-only import | ~484 |
| #20476 | " | 🔄 | EntityTypeValue type alias extracted from inline union for DRY and documentation | ~611 |
| #20475 | 7:05 PM | 🔵 | EntityType class maps discriminators to TypeScript declaration keywords | ~515 |
| #20471 | " | 🔄 | Final Import.test.ts isType reference removed and core codebase verified clean | ~588 |
| #20468 | " | 🔄 | toRecord test assertions updated for EntityType instance comparison | ~548 |
| #20467 | " | 🔄 | Completed migration of Import test suite to EntityType API | ~450 |
| #20465 | " | 🔄 | Import.test.ts updated to use EntityType instead of isType boolean in test cases | ~654 |
| #20463 | 7:04 PM | 🔄 | Import.test.ts migrated to EntityType-based test fixtures | ~204 |
| #20462 | " | 🔄 | Migrated mixed import test case from isType to EntityType discriminator | ~400 |
| #20460 | " | 🔄 | Updated Import test file to support EntityType-based import construction | ~356 |
| #20451 | 7:03 PM | 🟣 | Completed Identifier.toImport method implementation | ~457 |
| #20450 | " | 🟣 | Identifier.toImport method for direct ImportNameArg construction | ~585 |
| #20448 | " | 🔄 | Identifier.ts imports ImportNameArg type for toImport method preparation | ~511 |
| #20445 | " | 🔵 | Verified no circular dependency between Identifier and Import modules | ~364 |
| #20443 | 7:02 PM | 🔄 | Updated ImportName.toString to check EntityType discriminator instead of isType boolean | ~392 |
| #20442 | " | 🔄 | ImportName class field refactored from isType boolean to type EntityType | ~554 |
| #20441 | " | 🔄 | tagImportNameArg helper refactored to parse EntityType instead of isType boolean | ~583 |
| #20440 | " | 🔄 | Replaced isType boolean with type EntityType field in ImportNameArg | ~528 |
| #20439 | " | 🔄 | Updated statement-level import type detection to use EntityType discriminator | ~516 |
| #20438 | 7:01 PM | 🔄 | Import.toRecord refactored to use EntityType discriminator instead of isType boolean | ~575 |
| #20437 | " | 🔄 | Added EntityType import to Import.ts for identifier-based import construction | ~276 |
| #20419 | 6:59 PM | 🔵 | isType flag implementation across core DSL import system | ~592 |
| #20418 | " | 🔵 | Current isType boolean implementation in Import DSL | ~522 |
| #20417 | 6:58 PM | 🔵 | Import class implements three ImportNameArg shapes with statement-level type optimization | ~638 |
| #20416 | " | 🔵 | EntityType class maps variable and type entities to TypeScript keywords | ~468 |
| #20414 | " | 🔵 | Identifier class provides factory methods for variable and type entity creation | ~520 |

### May 12, 2026

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20971 | 2:58 PM | 🔵 | StackTrail location format discrepancy and cumulative fix status update | ~746 |
| #20655 | 8:47 AM | 🔵 | SKMTC ContentSettings and enrichment system | ~687 |
</claude-mem-context>