LinkML 1.10’s codegen pipeline deliberately separates annotation-bearing surfaces from data-validation surfaces. Treat this as a feature, not a bug.
Why: S3 spike 2026-05-02 verified that gen-typescript and gen-json-schema drop class-level + attribute-level annotations: (and extensions:) blocks under all flag combinations tried (--metadata, --no-metadata, --include-induced-slots, extensions:-instead-of-annotations:). Only description: (a first-class JSON Schema / JSDoc field) survives. By contrast, gen-pydantic preserves annotations via linkml_meta: ClassVar[LinkMLMeta] (class-level) and Field.json_schema_extra['linkml_meta']['annotations'] (attribute-level) when invoked with --meta full (or default --meta auto). This is not a defect — it’s LinkML’s deliberate design choice: TS interfaces + JSON Schema are runtime data-validation surfaces, the data shape; YAML + Pydantic are metadata + tooling surfaces, the schema metadata.
How to apply:
- For runtime metadata access in Python: invoke
~/tools/inherit-spike-env/bin/gen-pydantic --meta full schema.yamland read annotations viaMyClass.linkml_meta.root['annotations'](class-level) +MyClass.model_fields[<slot>].json_schema_extra['linkml_meta']['annotations'](attribute-level). - For build-time scope-binding / metadata-driven emission (e.g. Catala scopes filtered by
inherit:phase_activation_status): read the LinkML YAML directly viayaml.safe_load. The YAML is canonical; everything downstream is derived. Don’t rely ongen-json-schemaoutput for metadata. - For browser-side / wire-format metadata access (e.g. TS clients needing OntoUML stereotype info at runtime): emit a sidecar
*.metadata.jsonvia a ~10-line Python build script (parse YAML; project annotations into a flat metadata map). Or wait for LinkML 1.11.x/2.0 if it adds custom-annotation propagation to non-Python codegens. - Don’t treat TS / JSON-Schema annotation-drop as a “broken pipeline” → don’t try to fix it via custom Jinja templates or LinkML-version chasing. The architectural answer is YAML-as-canonical + Pydantic-runtime + sidecar-JSON-for-browser.
annotations:block vsextensions:block: identical generator support (both drop in TS+JSON-Schema; both preserve in YAML+Pydantic). Useannotations:(the LinkML community’s de-facto pattern for domain-specific metadata).extensions:is for typed extensions to LinkML schema language itself; not what you want for OntoUML/inherit:phase metadata.
Tooling pin (verified 2026-05-02 at S3 spike):
- LinkML 1.10.0 →
--meta fullflag (NOT--include-annotations=True— that flag does not exist; older docs/plans had wrong flag name) - Catala 1.1.0 →
typecheck --no-stdlibfor spike-level scope validation; production builds useclerk startfor full stdlib - node 24.14.1
--experimental-strip-types --checkfor TS syntactic validation without tsc
Source: T-spike-eps-iota-S3-ontouml-linkml-2026-05-02.md §3 (working configuration); arch-state v3.19 §11 S3 row + Changelog v3.19 row; plan v1.4 §1.8 + §2 Task 3 Step 3 + Step 7. PensionAsset (richard-task #213 deferred Year-2+) used as canonical phase-stereotype pilot class.
Related memories:
feedback_yaml_as_canonical_metadata_carrier— derived architectural pattern for INHERIT v2feedback_kill_condition_strict_vs_spirit_reading_via_outcome_MITIGATED— methodological framing of why TS+JSON-Schema annotation-drop isoutcome-MITIGATEDnotoutcome-KILL-CONDITION-METfeedback_surface_alternatives_before_collapsing_synthesis_to_baseline— informed the 5-alternative search at S3 (—meta/—no-metadata/—include-induced-slots/extensions/—no-stdlib) before settling on architecturally-correct YAML-as-canonical