Skip to content

Write JSON Schema properties in the LinkML's declared order - #45

Merged
jdkent merged 1 commit into
mainfrom
feat/declared-order
Oct 18, 2026
Merged

jdkent merged 1 commit into
mainfrom
feat/declared-order

Conversation

@jdkent

@jdkent jdkent commented Oct 18, 2026

Copy link
Copy Markdown
Member

The generated JSON Schemas list each class's properties alphabetically. The LinkML declares a deliberate order: Group, for example, keeps the counts together, then the criteria, then age_mean, age_standard_deviation, age_minimum, age_maximum, age_median, age_unit. Consumers that show fields in schema order lose it. neurostore's review app scattered the age fields across the card.

The order was lost in two places:

  • LinkML's JsonSchemaGenerator.serialize() dumps with sort_keys=True;
  • tools/generate_models.py sorts again.

Changes

  • render() takes the generator's dict (generate().to_json()) and sorts every key except each object's properties, which keep LinkML's induced slot order: parent slots first, so stable_id and local_id lead. $defs, top-level keys and each property's own keys stay sorted, so diffs stay stable.
  • The four schemas are regenerated. Each loads equal (==) to the previous version; only property order changes.
  • New tests/test_declared_order.py: every class's properties in all four schemas follow SchemaView.class_induced_slots, and generation is deterministic.
  • The README notes the order.

The Pydantic models are unchanged. Their field order differs from the LinkML in a few classes (the modality and *Details classes put stable_id/local_id or details_type first), which nothing reads by position.

The diff is large (+4887/−4874) but is reordering only. If #43 or #44 regenerate the schemas, they'll conflict here; regenerating after merging resolves it.

🤖 Generated with Claude Code

The generated JSON Schemas listed properties alphabetically: LinkML's
serialize() and tools/generate_models.py both sorted keys. Consumers that
show a class's fields in schema order (neurostore's review app) got age_sd
far from age_mean. render() now takes the generator's dict and sorts every
key except each object's properties, which keep the induced slot order.
The regenerated schemas load equal to the old ones; only property order
changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jdkent
jdkent merged commit 3464739 into main Oct 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant