Support current Hex Semantic Authoring YAML in hex adapter#202
Conversation
Update the Hex import adapter for the post-Aug-2025 schema while keeping legacy single-document files working: - Parse the top-level type: discriminator (model / view); untyped documents default to model for backward compatibility. - Read multi-document files separated by --- via yaml.safe_load_all instead of dropping everything after the first divider. - Add the view resource type (type: view with base + contents), preserved on model metadata and round-tripped back to type: view. - Map measure semi_additive (object form with over/pick) to non_additive_dimension. - Map dimension/measure name to display labels and visibility (public/internal/private) to public + meta on models, dimensions, and measures. - Export the type discriminator, names, visibility, and semi_additive back to current Hex YAML. Add a typed multi-document fixture plus tests, and un-xfail the semi_additive and visibility tests.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 815c0ee08e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Hex measures using semi_additive.over[].pick (e.g. pick: min for
opening-balance snapshots) or groupings previously only carried the
over dimension into Metric.non_additive_dimension. On export the adapter
re-emitted a minimal semi_additive: {over: [{dimension: ...}]} with no
pick, which the Hex spec defaults to max, silently changing the measure
semantics on import/export round-trips.
Stash the full object-form semi_additive config in measure meta on parse
and prefer it on export, so pick/groupings survive faithfully.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb643961cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The CLI/MCP directory loader detected Hex only by single-document yaml.safe_load plus a base_sql_table+measures heuristic. Current Hex Semantic Authoring projects are multi-document (---separated) typed resources, so safe_load raised before any Hex detection ran and 'sidemantic info' on a Hex project failed outright. Standalone exported type: view files were also silently skipped because they have neither base_sql_table nor measures. Detect Hex explicitly: a multi-document fallback using safe_load_all and a typed-resource check (type: model / type: view with an id) covering both legacy and current forms. Exempt Hex view resources, which are intentionally table-less presentation layers, from the physical-source validation requirement so they register cleanly.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a1f084ef7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Recognize base_sql_query as well as base_sql_table when selecting the Hex adapter so untyped query-backed Hex models load through load_from_directory instead of being silently skipped on the CLI/MCP path.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: afb3fb5661
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Reduce an inline semi_additive.over[].dimension object to its id so the Hex adapter no longer fails Pydantic validation on valid snapshot measures. Report Hex view resources whose base reference is missing or names an unknown model during directory validation instead of silently passing.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 552eff3337
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Hex view resources require contents in addition to a base reference. Report a view that omits contents during directory validation instead of silently passing, since views are exempt from the physical-source check.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f63e9e591
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Updates the Hex import/export adapter (
sidemantic/adapters/hex.py) to handle the current Hex Semantic Authoring YAML schema (post-Aug-2025), which the adapter previously broke on, while keeping legacy single-document files working.What changed
type:discriminator — every current Hex resource carries a top-leveltype:(model/view). The adapter now dispatches on it. Untyped legacy documents default tomodel, so existing single-doc fixtures keep parsing.---. Parsing switched fromyaml.safe_load(which silently dropped everything after the first divider) toyaml.safe_load_all.viewresource type —type: viewwithbase(target model id) andcontents(selection groups) is now parsed. Sidemantic has no native view concept, so the view structure is preserved on model metadata and round-trips back to atype: viewresource on export.semi_additivemeasures — the current object form (over: [{dimension, pick}]with optionalgroupings) maps to Sidemantic'snon_additive_dimension.name—nameon models/dimensions/measures maps to the Sidemantic display label.visibility—public/internal/privateon models, dimensions, and measures is recorded in metadata and reflected in thepublicflag (onlypublicstays visible).Export emits the
typediscriminator, display names, visibility, and the object-formsemi_additiveback to current Hex YAML.Tests and fixtures
tests/fixtures/hex/subscriptions_project.yml) containing amodeland aview, plustests/adapters/hex/test_typed_resources.pycovering parsing, the view resource, labels, visibility, semi-additive, and import/export round-trips.saas_analytics.ymlandproduct_events.ymlto the current typed + object-formsemi_additiveshape and un-xfailed thesemi_additiveandvisibilitytests.Verified against the Hex
learn.hex.techsemantic-models modeling specification.Known limitations
viewis imported as a metadata-bearing, field-less model (faithful round-trip), not expanded into a fully resolved model against its base.visibilityon relations is not mapped (theRelationshipcore type has no visibility field); it is scoped to models, dimensions, and measures.semi_additive.pickandgroupingsare preserved only insofar as the firstoverdimension maps to the singlenon_additive_dimension.