Skip to content

feat(ir): write the compact canonical v4 spelling by default - #48

Merged
DamianReeves merged 3 commits into
mainfrom
DamianReeves/v4-compact-writer
Oct 28, 2026
Merged

DamianReeves merged 3 commits into
mainfrom
DamianReeves/v4-compact-writer

Conversation

@DamianReeves

Copy link
Copy Markdown
Member

OpenSpec change write-compact-ir-v4, the writer half of bead morphir-ukvn.8.16 (group morphir-ukvn.8.16.1).

The pinned finos/morphir v4 JSON profile (efa36060, unchanged upstream) says writers SHOULD emit the compact canonical vocabulary. This repository's writer emitted only the expanded spelling and the pre-decision nested {doc, value} wrapper, 30–35% larger than morphir-core's output.

  • Compact by default. A node without attributes takes its shortest form, following morphir-core 0.2.0's serde_v4.rs:

    • types: a variable or an argument-free reference as a string, an applied reference as {"Reference": [fqn, args...]}, a tuple as {"Tuple": [...]};
    • values: Literal, Constructor, Reference, Variable, FieldFunction, Tuple and List with the payload directly under the tag;
    • patterns: TuplePattern and LiteralPattern the same way.

    A node with attributes keeps the expanded spelling, attributes first.

  • Flattened documentation. doc comes first beside documented types and values (decision 0010). Module definitions keep doc after types and values, as morphir-core writes them.

  • Expanded on request. Spelling.EXPANDED, passed as spelling= or selected with the use_spelling context manager (task-local), and morphir-python ir convert --v4-spelling expanded.

  • BREAKING for consumers that accept only the expanded spelling. Every schema-valid reader, including this library and morphir-core, reads both.

Out of scope, still deferred on upstream: legacy-spelling warnings, kit diagnostic renames, Union and 4.1.0 annotations, and the morphir-diwy downgrade codes.

Verification

  • The morphir-core 0.2.0 compiler fixtures decode and re-encode byte for byte.
  • Expanded output equals golden files captured from the previous writer.
  • A walker finds no compact node in expanded output of three fixtures, and both spellings decode to the same model.
  • Each compact node form has a unit test. CLI tests cover the default, expanded output, a rejected value, and v3 unaffected.
  • mise run check: lint, format, mypy and pyright strict, 2498 tests, 34 behave scenarios. stubtest and the use_spelling doctest pass.

The writer half of morphir-ukvn.8.16: write the compact canonical v4
spelling the profile prefers, flatten documentation per decision 0010,
and keep the expanded spelling selectable.
The v4 encoders now write a node without attributes in its shortest
schema-valid form, as morphir-core 0.2.0 writes it, and keep the
expanded form for nodes with attributes. Compiler output decodes and
re-encodes byte for byte. Documentation is flattened with doc first
instead of the nested {doc, value} wrapper. Spelling.EXPANDED, passed
as spelling= or selected with use_spelling, writes every node expanded,
and ir convert gains --v4-spelling. Golden files prove the expanded
output is otherwise unchanged; tests that quote expanded upstream or
reader cases now select it explicitly.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T02:22:25.412921Z 726ac9d Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@DamianReeves

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 726ac9d800

ℹ️ 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".

Comment on lines +898 to +899
case "Variable":
return members["name"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Retain a tagged spelling for non-lowercase type variable names

When a type variable's canonical name contains an initialism or starts with a digit, returning its name as a bare string produces output that the decoder rejects. For example, decode_type({'Variable': {'name': 'USD'}}) succeeds, but encoding that model now yields 'USD', which fails in _decode_type_string because _TYPE_VARIABLE_STRING permits only lowercase-leading names with lowercase/digit segments. The same regression occurs for valid names such as item-USD and 123, so default serialization can make previously readable distributions unreadable. Use the bare string only when it matches the type-variable string grammar, and otherwise retain a tagged variable spelling.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: decode_type({"Variable": {"name": "USD"}}) re-encoded to "USD", which the bare type-variable grammar rejects. Fixed in e66a00d: the writer uses the bare string only when it matches _TYPE_VARIABLE_STRING, and otherwise writes {"Variable": name}, which is still compact. Added test_a_variable_outside_the_bare_string_grammar_keeps_its_tag for USD, item-USD and 123; the full suite passes, 2501 tests.

…ammar

The schema's bare type-variable string is lowercase only, so names such
as USD, item-USD or 123 were written in a form the reader rejects. Write
them as {"Variable": name}, which is still compact and reads back.
@DamianReeves
DamianReeves merged commit 95ca93d into main Oct 28, 2026
10 checks passed
@DamianReeves
DamianReeves deleted the DamianReeves/v4-compact-writer branch October 28, 2026 03:34
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