Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@
<title>write-compact-ir-v4: design</title>
<!--
Agent document template (docs/templates/agent-document.html). Specs, plans and reports that a person reviews
start from this file: copy it, keep the <head> as it is, and write the content inside <main>
start from this file: copy it, keep the <head> as it is, and write the content inside <main>.
Styles and scripts are files in docs/templates/assets/, referenced and not embedded. In a copy, change the
"assets/" prefix of each href and src to the relative path from the copy to that directory, for example
"../../docs/templates/assets/" from .dev/beads-specs/. See AGENTS.md, "Specs and plans are HTML documents".
Code goes in <pre><code class="language-python"> (or json, toml, bash, diff). Give sections an id and
list them in nav.toc.
-->
<link rel="stylesheet" href="../../../../docs/templates/assets/agent-document.css">
<link rel="stylesheet" href="../../../../docs/templates/assets/highlight/styles/github.min.css" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="../../../../docs/templates/assets/highlight/styles/github-dark.min.css" media="(prefers-color-scheme: dark)">
<script defer src="../../../../docs/templates/assets/highlight/highlight.min.js"></script>
<script defer src="../../../../docs/templates/assets/agent-document.js"></script>
</head>
<body>
<main>
<h1>write-compact-ir-v4</h1>
<p class="meta">OpenSpec change write-compact-ir-v4 · Bead morphir-ukvn.8.16 · 2026-10-27 · Proposed</p>

Expand Down
29 changes: 29 additions & 0 deletions openspec/specs/ir/v4/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,32 @@ The Python `Native` and `External` value nodes and the structured type constrain
#### Scenario: Deprecated value node still refuses to encode
- **WHEN** a caller encodes a value that contains a Python `Native` value node
- **THEN** encoding fails with `no_v4_spelling`, and the documentation directs the caller to a native definition body

### Requirement: Write the compact canonical v4 spelling
By default, the v4 encoders SHALL write the compact canonical spelling of the pinned finos/morphir v4 JSON profile, as morphir-core writes it at the same profile. A node without attributes SHALL use its shortest schema-valid form, and a node that carries attributes SHALL keep the expanded spelling with `attributes` first. (bead: morphir-ukvn.8.16)

#### Scenario: Compiler output re-encodes byte for byte
- **WHEN** a v4 document written by morphir-core 0.2.0 for a compiled Python model is decoded and encoded with the default spelling
- **THEN** the encoded JSON equals the original document, including member order

#### Scenario: Compact node forms
- **WHEN** a model with type variables, argument-free and applied type references, tuples, literals, variables, references, constructors, field functions, lists, tuple patterns and literal patterns is encoded
- **THEN** they are written as name or FQName strings, `{"Reference": [fqname, args...]}`, `{"Tuple": [...]}`, `{"Kind": payload}` literals, and wrappers holding their payload directly

#### Scenario: Attributes keep the expanded spelling
- **WHEN** a type or value carrying a source location or an inferred type is encoded
- **THEN** that node is written in the expanded spelling with `attributes` first, while nodes without attributes stay compact

### Requirement: Write documentation flattened
The v4 encoders SHALL write documentation flattened, with `doc` first beside the documented node's own members (decision 0010), and SHALL NOT write the nested `{"doc", "value"}` wrapper. (bead: morphir-ukvn.8.16)

#### Scenario: Documented type definition
- **WHEN** a documented type definition is encoded
- **THEN** `doc` is its first member, followed by the definition's members, and decoding returns the same documentation and definition

### Requirement: Select the expanded spelling
Callers SHALL be able to select the expanded spelling, which writes every node in its expanded form. Both spellings SHALL decode to the model that was encoded. (bead: morphir-ukvn.8.16)

#### Scenario: Expanded spelling on request
- **WHEN** a caller selects the expanded spelling for a model
- **THEN** every node is written expanded, and decoding returns the same model as decoding the default output
11 changes: 11 additions & 0 deletions openspec/specs/tools/ir-interchange/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,14 @@ The tools MUST reject any 3.x release from 3.2.0 on, and any major outside the s
#### Scenario: Unsupported format version is named
- **WHEN** the user supplies a file whose `formatVersion` is `"3.2.0"` or 5
- **THEN** the tool exits non-zero with the format-version diagnostic code and says only 3.0.x, 3.1.x and draft 4.0.x are supported

### Requirement: Choose the v4 spelling on conversion
`ir convert --to v4` SHALL write the compact canonical spelling by default and SHALL accept `--v4-spelling expanded` to write the expanded spelling. The option SHALL be rejected as a usage error with any other value, and SHALL have no effect on v3 output. (bead: morphir-ukvn.8.16)

#### Scenario: Default conversion is compact
- **WHEN** the user converts a format 3 file with `ir convert --to v4`
- **THEN** the written document uses compact spellings, such as type references as FQName strings, and `ir inspect` reads it

#### Scenario: Expanded conversion on request
- **WHEN** the user adds `--v4-spelling expanded`
- **THEN** the written document uses the expanded spellings and decodes to the same model as the compact output
Loading