{
  "$comment": "The single source of openeik.org/conformance, for the current version, 0.4. It must agree with the specification at spec main (openeik/spec): spec/09-conformance.md (the classes, what Parts XIII to XVIII add to each, how a claim is checked, the reference implementation's status), spec/10-open-questions.md section 2 (what the reference implementation does not meet yet), spec/README.md (the version and its status) and packages/openeik (its README and its tests). Update it with every change to them, in the same change, and set `updated`. Change the test numbers only after running the tests again, in a copy of spec main: `node --test packages/openeik/test/*.test.mjs` and `node tools/run-conformance.mjs`; record the date, the commit and the Node.js version. `tests.earlier` keeps each earlier version's figures as its tag has them: they do not change. Then run `node tools/conformance.mjs` to refresh the page's no-script copy (`--check` says whether it is current). Text in `backticks` is shown as code, and [text](/path) as a link; links to the specification are /spec/0.4/<part>#<section number>, and to an earlier version's text under its own series. No client, supplier or firm names. Every statement needs a source.",
  "updated": "2026-11-01",
  "version": "0.4.0",
  "draft": {
    "label": "Tagged privately",
    "text": "OpenEik 0.4.0 is tagged `v0.4.0` and not yet published. It keeps every class and requirement of 0.3 and adds the rules of seven sections. OpenEik 0.3 is kept at the tag `v0.3.0`, 0.2 at `v0.2.3` and 0.1 at `v0.1.0`; a claim to 0.3 is a claim to its twelve classes as that tag has them ([Conformance in 0.3](/spec/0.3/conformance)), a claim to 0.2 to its twelve as the tag `v0.2.3` has them ([Conformance in 0.2](/spec/0.2/conformance)), and a claim to 0.1 to its eight, without the requirements of Parts XIII to XVIII, which were proposals in 0.1 ([Conformance in 0.1](/spec/0.1/conformance))."
  },
  "classes": {
    "eyebrow": "The classes",
    "h2": [
      "{n} classes.",
      "An implementation claims one or several."
    ],
    "lede": "Each class lists the sections of the specification an implementation must meet to claim it; Parts XIII to XVIII add to most of them, each in its own section on conformance. In short:",
    "list": [
      {
        "id": "reader",
        "name": "Reader",
        "does": "Reads models.",
        "must": "Reads a model's folder, checking the format in `eik.json` first and needing no built-in library, and reads its single-file form too. Refuses what it cannot read, the list of Part III, 12. The whole-model check is a SHOULD: a reader that performs it refuses a folder that fails it, and one that does not reads the folder as it is. Keeps unknown members, elements and types of unknown categories, profile members, application records and values, kept files and declared geometry, all unchanged. Leaves alone a kept file whose name a file system refuses or reads otherwise, or whose path folds to another of the model's or passes through `eik.json` or `AGENTS.md`, and reads on; refuses a version that no folder gives, one that holds such a file among them. It SHOULD also read a model of 0.1, by 0.1's rules, and otherwise refuses it, naming its version. Of Parts XIII to XVIII it reads circuits, sheets and people as records, the electrical categories and the drawing files as those parts define them, the files of `assets/`, `project/owners.json`, and the files of reviews and issues.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part III, 12",
            "href": "/spec/0.4/code-base#12"
          },
          {
            "text": "Part III, 7",
            "href": "/spec/0.4/code-base#7"
          },
          {
            "text": "Part I, 10",
            "href": "/spec/0.4/foundations#10"
          },
          {
            "text": "Part I, 9.6",
            "href": "/spec/0.4/foundations#9.6"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "validator",
        "name": "Validator",
        "does": "Says whether a model is valid, and why not.",
        "must": "Everything a reader must do, and the whole-model check: validates every file against its schema and checks the rules of Parts I and II, among them two records' paths that fold to one and an id's length; checks the stored form and the paths, and reports a file not in the stored form and a record at a path that disagrees with it as errors; reports each kept file a reader leaves alone, as a warning in a folder and as an error in the single-file form; and names the file and the rule of every failure. It never refuses an unknown member, an extension member or a record of an unknown category. Of Parts XIII to XVIII it checks the rules each lists for it: an electrical installation's, those of the drawings that the folder decides, those of `assets/` and of `project/owners.json`, and those of reviews, issues, receipts and terms accepted.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part III, 12",
            "href": "/spec/0.4/code-base#12"
          },
          {
            "text": "Part I, 6",
            "href": "/spec/0.4/foundations#6"
          },
          {
            "text": "Part III, 3",
            "href": "/spec/0.4/code-base#3"
          },
          {
            "text": "Part III, 4.2 and 5",
            "href": "/spec/0.4/code-base#4.2"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "writer",
        "name": "Writer",
        "does": "Writes models.",
        "must": "Writes each record at its path in the stored form, with `eik.json` and every type that a record names, and leaves kept files alone. It keeps the members of `eik.json` it does not know, and refuses a model with two records whose paths fold to one, an id whose path segment is longer than 200 bytes, or a kept file whose name a file system refuses or reads otherwise, or whose path folds to another of the model's or passes through `eik.json` or `AGENTS.md`. It never writes derived data into a record, nor costs, prices or quotes. Of Parts XIII to XVIII it writes circuits, sheets and people at their paths and a view's lighting scene, keeps issued files, and writes no asset of a kind 0.2 does not define.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part III, 13",
            "href": "/spec/0.4/code-base#13"
          },
          {
            "text": "Part I, 6",
            "href": "/spec/0.4/foundations#6"
          },
          {
            "text": "Part III, 7",
            "href": "/spec/0.4/code-base#7"
          },
          {
            "text": "Part III, 8.1",
            "href": "/spec/0.4/code-base#8.1"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "compiler",
        "name": "Compiler (core)",
        "does": "Derives bodies from records.",
        "must": "Derives bodies by the class-A rules of Part IV: layered extrusions, outline edges trimmed to a wall's face, roof planes, attached tops, member sweeps, rectangular openings, the line and given posts of a railing on an outline, and a generic element's declared bodies. It stores nothing derived in a record, and where a supplier declares geometry, it uses it and derives nothing beyond what the declaration is authoritative for. Of Part XIII it derives the bodies of an electrical installation.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part IV, 2",
            "href": "/spec/0.4/compiler#2"
          },
          {
            "text": "Part XIII, 7",
            "href": "/spec/0.4/electrical#7"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "command-processor",
        "name": "Command processor",
        "does": "Changes models by commands.",
        "must": "Changes a model by typed commands, the core record operations at least: each is checked before anything changes and applied all or nothing, and the whole model is checked after every command. It never creates an element or a type of a category it does not know. Of Parts XIII to XVIII it takes the electrical and the drawing commands, says which owners a change's paths need, and takes Part XVII's envelopes and bare batches: an operation applied once, its target and its mode, a precondition on every command, refusals with codes, and the answer.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part V, 2.1",
            "href": "/spec/0.4/commands#2.1"
          },
          {
            "text": "Part XVII, 13",
            "href": "/spec/0.4/envelope#13"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "version-store",
        "name": "Version store",
        "does": "Keeps versions.",
        "must": "Keeps a model's versions as git keeps code: content-addressed objects, trees, versions, and refs moved by compare-and-swap, with diff and three-way merge by record and field. When it fetches from, pushes to, pulls from or clones a remote, it meets Part VI, 6 as well. It keeps issued files and assets in its versions, and meets Part XV, 5 and 6 for assets in a store, a push, a fetch, a pull and a clone.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part VI",
            "href": "/spec/0.4/history"
          },
          {
            "text": "Part XV, 5",
            "href": "/spec/0.4/assets#5"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "agent-host",
        "name": "Agent host",
        "does": "Serves models to agents.",
        "must": "Offers an agent the operations of Part VII, under any names and through any protocol: a summary, the tree, tiered reads, commands, validation and the guide, all working headless. It is also a reader, and if it writes, a writer and a command processor. It authenticates and attributes the envelopes it takes.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part VII, 1",
            "href": "/spec/0.4/agent-interface#1"
          },
          {
            "text": "Part XVII, 4.2",
            "href": "/spec/0.4/envelope#4.2"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "bridge",
        "name": "Bridge",
        "does": "Exports to another format.",
        "must": "Meets Part VIII, 1 for each format it claims. For IFC: every element of the core categories that has a body, with its type, its level and its openings, generic elements included, and a fidelity report with every export that says what it leaves out or approximates. A print names the version it was printed from.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part VIII, 1",
            "href": "/spec/0.4/bridges#1"
          },
          {
            "text": "Part XVIII, 7.2",
            "href": "/spec/0.4/review#7.2"
          },
          {
            "text": "Conformance, 1.1",
            "href": "/spec/0.4/conformance#1.1"
          }
        ]
      },
      {
        "id": "drawing-validator",
        "name": "Drawing validator",
        "does": "Checks issued drawings.",
        "must": "Everything a validator must do, and more of an issued drawing: works out whether it is current from what it was drawn from, verifies its sign-offs, and checks the rules that need the history where it has it. It verifies signed issues, a host's receipts and terms accepted, given the hosts' keys and the time-stamp authorities' certificates.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part XIV, 19.2",
            "href": "/spec/0.4/drawings#19.2"
          },
          {
            "text": "Part XVIII, 9",
            "href": "/spec/0.4/review#9"
          }
        ]
      },
      {
        "id": "drawing-issuer",
        "name": "Drawing issuer",
        "does": "Issues drawings.",
        "must": "Issues drawings in the SVG profile, with their files, records and register, a complete read set and output that is the same for the same input. It issues no drawing while a view on the sheet holds an item an agent proposed, and never an SVG written by hand.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part XIV, 19.2",
            "href": "/spec/0.4/drawings#19.2"
          },
          {
            "text": "Part XIV, 6",
            "href": "/spec/0.4/drawings#6"
          }
        ]
      },
      {
        "id": "host",
        "name": "Host",
        "does": "Keeps a project's versions for several parties, and serves its reviews and issues.",
        "must": "Everything a version store must do, and holds a change for its owners' approvals. It keeps the events of an issue and offers receipts, publishes the keys it signs them with, and keeps the security and privacy rules of review and issue.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part XVI, 4",
            "href": "/spec/0.4/ownership#4"
          },
          {
            "text": "Part XVIII, 9",
            "href": "/spec/0.4/review#9"
          }
        ]
      },
      {
        "id": "authoring-tool",
        "name": "Authoring tool",
        "does": "Makes the model people issue.",
        "must": "Everything a writer must do, and saves what a host offers it, and records a named version of what it issues.",
        "refs": [
          {
            "text": "Conformance, 1",
            "href": "/spec/0.4/conformance#1"
          },
          {
            "text": "Part XVIII, 9",
            "href": "/spec/0.4/review#9"
          },
          {
            "text": "Part XVIII, 3.2",
            "href": "/spec/0.4/review#3.2"
          }
        ]
      }
    ],
    "note": "A requirement on “an implementation” applies to every class that performs the act it names ([Part I, 2](/spec/0.4/foundations#2)). Clash and layout checks are not a conformance class ([Conformance, 1](/spec/0.4/conformance#1))."
  },
  "claim": {
    "eyebrow": "A claim",
    "h2": [
      "Meet every requirement of a class,",
      "then name the version and the classes."
    ],
    "quote": "An implementation conforms to OpenEik 0.4 in one or more classes. It claims a class by meeting every requirement this page lists for it; it MAY claim several. A claim names the version (`OpenEik 0.4.0`) and the classes, for example \"OpenEik 0.4.0 reader and validator\". A claim to 0.3 (`OpenEik 0.3`) is a claim to the classes of 0.3 as the tag `v0.3.0` has them, the same twelve without the rules 0.4 adds; a claim to 0.2 (`OpenEik 0.2`), to those of 0.2 as the tag `v0.2.3` has them, without the rules 0.3 adds; a claim to 0.1 (`OpenEik 0.1`) is a claim to the classes of 0.1 as the tag `v0.1.0` has them: eight, without the requirements of Parts XIII to XVIII, which were proposals in 0.1.",
    "source": {
      "text": "OpenEik 0.4, Conformance",
      "href": "/spec/0.4/conformance"
    },
    "checkedTitle": "How a claim is checked",
    "checked": [
      {
        "name": "Schemas",
        "text": "`schemas/0.4/` holds a JSON Schema (2020-12) for every kind of file of 0.4, and `schemas/0.4/index.json` maps paths to them; `schemas/0.3/` holds those of 0.3, `schemas/0.2/` those of 0.2 and `schemas/` those of 0.1 beside them, for reading a model of 0.3, 0.2 or 0.1."
      },
      {
        "name": "The check tool",
        "text": "`tools/check.mjs` checks a folder or a single-file model against the schemas, the stored form, the paths, unique ids, references and the format version, and the rules that need geometry or the types' sizes. It is a partial validator: it does not check the framing families' expression language and parameters, or that a sheet section follows its profiled sheet."
      },
      {
        "name": "The examples",
        "text": "`examples/` holds two folders written by the reference implementation and migrated to 0.2. A reader MUST read both without error. A writer that reads one and writes it back without changes MUST write every record file it keeps byte for byte as it was."
      },
      {
        "name": "Compiler vectors",
        "text": "Conformance vectors for the compiler ([Part IV, 10](/spec/0.4/compiler#10)) are not published yet. The pipe and duct fixtures of Part IV, 12.5 are a first set."
      },
      {
        "name": "Model quality",
        "text": "`openeik check --quality` warns about elements modelled under a category that does not fit them. These warnings are heuristics: no claim depends on them."
      }
    ],
    "checkedSource": {
      "text": "Conformance, 2",
      "href": "/spec/0.4/conformance#2"
    },
    "notDefinedTitle": "Not defined in 0.4",
    "notDefined": [
      "Who checks a claim.",
      "Where a claim is published, or a register of claims.",
      "A certificate, logo or mark that goes with a claim.",
      "What evidence a claim carries, or the form of a test report.",
      "Whether a SHOULD that is not met stands in the way of a claim."
    ]
  },
  "tests": {
    "eyebrow": "Tests",
    "h2": [
      "The library's own tests,",
      "and a conformance suite for every implementation."
    ],
    "library": {
      "label": "Today",
      "title": "The tests of `@openeik/tools`",
      "tests": 3098,
      "files": 75,
      "passed": 3093,
      "failed": 0,
      "skipped": 5,
      "date": "2026-11-01",
      "commit": "9077aa6c",
      "node": "22.23.3",
      "covers": "They cover the reader, the validator and its rules, the writer, the command processor, the compiler, canonical JSON and hashes, JSON that is not I-JSON, version trees, diff, merge, stores and remotes, result manifests, model quality, changes by discipline folder and the datums every discipline shares, the building physics of materials, layers, types and the project's envelope, which way walls, doors, windows and roof windows face, heating, ventilation and plumbing (systems, insulation by code and thickness, heat on terminals, components in a pipe or a duct and their bodies, every terminal's box, a view's filter by system, tags and symbols), the outline of a slab whose edges are trimmed to a wall's face as a reader takes it without compiling, the bodies of slab edge elements and gutters and the openings shafts cut, how doors and windows open, with the validator's findings on its trims, clashes between building services and the building, commands in an envelope, with an operation applied once, coded refusals and a precondition on every command, the IFC bridge (`ifcOfModel`: a print of a version, the same bytes each time, plates and bolt groups as plates and fasteners, and what buildingSMART's normative rules check of types, operations, solids and placements, every closed face set holding a volume, an application's bodies where the compiler derives none, imported property sets typed by IFC4's templates where the record says its numbers' units), sections with rounded corners and of any outline, an experimental IFCX print of the same objects (`ifcxOfModel`, buildingSMART's alpha), a review of the model at a version, its anchors checked against that version, issues signed and received, receipts and terms accepted, the versions of a model, 0.1 and 0.2, read and written, a model of 0.1 migrated to 0.2, the schemas of 0.2, the `openeik` command, every case of the conformance suite of 0.2, with the whole-model check and without it, and what 0.2 made rules of 0.1's proposals: electrical installations, drawings with their SVG profile, freshness, the verification of sign-offs and a review exported as BCF, ownership by folder and folders that follow owners, assets kept by the SHA-256 of their bytes, carried in versions, pushes, clones and pulls, a door's and a window's own body, a stair's numbers and the layout of straight, L and U stairs, a layer's grain and an element's main direction, a framing family's parts, a wall's, a roof's and a floor's timber framing laid out, reading IFC into OpenEik, a site's true north and map coordinates, classification references, a hosted railing's profile, declared geometry in its frame, retired component families, a room's boundary, ceiling and quantities, members between two points, sloped slabs and provisions for voids.",
      "skippedWhy": "Three skipped tests need a checkout of a store's server, one a building with every pipe, duct and fixture type, which the repository does not hold, and one a Python with IfcOpenShell to validate an IFC print.",
      "runWhere": "at the root of the specification repository (public at launch)",
      "run": "npm ci && npm test",
      "note": "They test this library, not other implementations."
    },
    "suite": {
      "label": "For every implementation",
      "status": "draft",
      "statusLabel": "In the draft",
      "title": "The conformance suite",
      "text": "1080 cases, one suite for 0.4, in `conformance/` of the specification repository (public at launch), and here as one zip, [openeik-conformance-0.4.zip](/conformance/openeik-conformance-0.4.zip): 52 of Part I, 387 of Part II, 100 of Part III, 88 of Part IV, 3 of Part V, 3 of Part VI, 21 of the security and privacy considerations, 106 of Part XIII, 79 of Part XIV, 8 of Part XV, 20 of Part XVI, 143 of Part XVII and 70 of Part XVIII, each checked with no proposal. 877 of them are for the validator class, 319 for the reader, 187 for the command processor and 16 for the drawing validator. Most are a small model, a folder or a single file, that differs from one valid model by one change, with an `expected.json` that quotes the rule it tests and says what a validator reports and what a reader does: reads the model, refuses it, or either, where the specification allows both, as for a model that fails only the whole-model check ([Part III, 12](/spec/0.4/code-base#12)). A command processor's case gives the messages sent to it and the answers it gives; the forms `freshness`, `verify` and `anchors` work out whether issued drawings are current, verify signed statements and check a review's anchors. Beside them, `conformance/migration/` holds a folder of 0.1 and the folder of 0.2 the migration makes of it ([Part I, 9.8](/spec/0.4/foundations#9.8)), `migration-0.3/` a folder of 0.2 and the folder of 0.3 ([9.9](/spec/0.4/foundations#9.9)), and `migration-0.4/` a folder of 0.3 and the folder of 0.4 ([9.10](/spec/0.4/foundations#9.10)). The suite is data, and its README says what a runner of your own does with each case. In the repository, `node tools/run-conformance.mjs` runs them against `@openeik/tools`, or against another implementation through an adapter; `@openeik/tools` passes all 1080, and passes them too as a reader that skips the whole-model check (`--unchecked`). Test vectors for compilers are not published yet ([Conformance, 2](/spec/0.4/conformance#2))."
    },
    "earlier": [
      {
        "version": "0.1",
        "text": "As the tag `v0.1.0` has it: the library's tests at `45cb7d88`, 2242 in 68 files, 2237 passed, 0 failed and 5 skipped, run on 30 October 2026 with Node.js 22.23.3; and the conformance suite of 0.1, 335 cases for the reader and validator classes, with 678 more for its proposals for 0.2, in [openeik-conformance-0.1.zip](/conformance/openeik-conformance-0.1.zip), all of which `@openeik/tools` 0.1.0-draft passes. Its eight classes: [Conformance in 0.1](/spec/0.1/conformance)."
      }
    ]
  },
  "implementations": {
    "eyebrow": "Implementations",
    "h2": [
      "Where the implementations stand,",
      "on {asOf}."
    ],
    "asOf": "2026-10-30",
    "lede": "The reference implementation, and the library in the specification repository. Each row names its sources.",
    "list": [
      {
        "id": "stomra",
        "name": "Stomra",
        "what": "The reference implementation: Stomra's engine and its `ek` command. The specification is written from it, and it is the evidence that each requirement can be met.",
        "link": "https://stomra.com",
        "linkText": "stomra.com",
        "summary": "It reads and writes OpenEik 0.1, and refuses a folder of 0.2, so it claims no class of 0.2 yet. With a model of 0.1 it meets most of the requirements of the eight classes of 0.1.",
        "notes": [
          "Of 0.2's records, it reads and writes the devices, boards and circuits of [Part XIII](/spec/0.4/electrical) (its works 532 and 534), and issues drawings in [Part XIV](/spec/0.4/drawings)'s files since its work 566, from sheets that are still application records of 0.1."
        ],
        "classes": [
          {
            "class": "reader",
            "state": "meets most"
          },
          {
            "class": "validator",
            "as": "`ek validate`",
            "state": "meets most"
          },
          {
            "class": "writer",
            "state": "meets most"
          },
          {
            "class": "compiler",
            "state": "meets the class-A rules"
          },
          {
            "class": "command-processor",
            "state": "meets most"
          },
          {
            "class": "version-store",
            "state": "meets most"
          },
          {
            "class": "agent-host",
            "as": "`ek`, `ek-mcp`",
            "state": "meets"
          },
          {
            "class": "bridge",
            "as": "IFC",
            "state": "meets for IFC4"
          },
          {
            "class": "drawing-validator",
            "state": "not met"
          },
          {
            "class": "drawing-issuer",
            "state": "not claimed"
          },
          {
            "class": "host",
            "state": "not a host: it pushes to one"
          },
          {
            "class": "authoring-tool",
            "state": "not yet stated"
          }
        ],
        "gapsTitle": "Not met yet",
        "gaps": [
          {
            "topic": "Versions",
            "text": "Reads and writes OpenEik 0.1 only: it refuses a folder or a version of 0.2, writes `openeik/0.1-draft` in 0.1's folders, not the owners', and makes no migration ([Part I, 9.2](/spec/0.4/foundations#9.2) and [9.8](/spec/0.4/foundations#9.8); [Part III, 4.4](/spec/0.4/code-base#4.4))."
          },
          {
            "topic": "Unknown and generic categories",
            "text": "Refuses an element or a type of a category it does not know, `generic` among them ([Part I, 10](/spec/0.4/foundations#10); [Part II, 6.6](/spec/0.4/language#6.6))."
          },
          {
            "topic": "Built-in library",
            "text": "Adds its built-in library, about 250 types, to every model it loads, and writes it into every folder it exports; the library holds five types of a category 0.1 does not have ([Part III, 12 and 13](/spec/0.4/code-base#12); [Part II, 6.2](/spec/0.4/language#6.2))."
          },
          {
            "topic": "Ids and paths",
            "text": "Accepts `/` in ids other than those of originals and copies, checks ids for uniqueness in some lists only, and does not report a file whose path disagrees with its record. It compares no paths by their folds and bounds no id's path segment: its validator accepts, and its writer writes, two records whose paths fold to one and ids whose segments are longer than 200 bytes ([Part I, 6](/spec/0.4/foundations#6); [Part III, 4.2](/spec/0.4/code-base#4.2) and [4.3](/spec/0.4/code-base#4.3))."
          },
          {
            "topic": "Kept files",
            "text": "Keeps as kept files, and writes, the files a reader leaves alone: those whose names a file system refuses or reads otherwise, those whose paths fold to another of the model's, and those under a folder named `AGENTS.md`. It reads a version that a reader refuses: one that holds such a file, a kept text over 1 MiB or with NUL, or a hidden name ([Part III, 7](/spec/0.4/code-base#7); [Security and privacy, 5.3](/spec/0.4/security-and-privacy#5.3))."
          },
          {
            "topic": "Versions it saves",
            "text": "Saves versions that a 0.1 reader refuses: with a kept file that Part III, 7, rule 8 leaves out, `AGENTS.md/notes.md` among them; with a kept text over 1 MiB or with NUL, from a single-file model it imports; and, before Stomra 506, with a record or a level whose id starts with `.` under a hidden name ([Security and privacy, 5.3](/spec/0.4/security-and-privacy#5.3); [Open questions, 2](/spec/0.4/open-questions#2))."
          },
          {
            "topic": "Members of its own",
            "text": "Writes members and a value 0.1 does not define without a prefix (`notches`, `textBackground`, `person`, the `pattern` value `clt`), where 0.1 asks for extension members under a registered prefix; each joins 0.2 or becomes its extension member under its prefix ([Part I, 11.2](/spec/0.4/foundations#11.2); [open question 115](/spec/0.4/open-questions#3)). It names its single-file models `*.stomra.json`, where a SHOULD asks for `*.eik.json` ([Part III, 11.1](/spec/0.4/code-base#11.1))."
          },
          {
            "topic": "Members of `eik.json`",
            "text": "Keeps the members of `eik.json` it does not know only in a folder whose `eik.json` names `openeik/0.1-draft` in mm: it writes its own over one that names another format id of 0.1, and holds its own in every version it saves, without them ([Part III, 8.1](/spec/0.4/code-base#8.1))."
          },
          {
            "topic": "Commands",
            "text": "Refuses a member it does not know in an element, a patch or a view, and drops one in a type or at a command's top level ([Part V, 1](/spec/0.4/commands#1))."
          },
          {
            "topic": "Declared geometry",
            "text": "Accepts a `swept` body and the `line` frame in a declaration of any category, and draws a type's declared envelope for railing types only ([Part II, 12.1](/spec/0.4/language#12.1); [Part IV, 11.1](/spec/0.4/compiler#11.1))."
          },
          {
            "topic": "Compiler",
            "text": "Builds no derived layer, which is optional ([Part IV, 1.1](/spec/0.4/compiler#1.1))."
          },
          {
            "topic": "IFC",
            "text": "A SHOULD asks the fidelity report to name the bodies that are declared envelopes; it marks each such element in a property set of the IFC file instead ([Part IV, 11.1](/spec/0.4/compiler#11.1))."
          },
          {
            "topic": "Records of 0.2",
            "text": "Writes emergency luminaires as `fire` elements ([Part XIII, 2.3](/spec/0.4/electrical#2.3)), and a railing's copy of an outline ([Part II, 12.2.1](/spec/0.4/language#12.2.1)); has no member between two points and no sloped slab ([Part II, 6.2.1](/spec/0.4/language#6.2.1) and [6.3.1](/spec/0.4/language#6.3.1)), no device's protective earth ([Part XIII, 2.2](/spec/0.4/electrical#2.2)), and no frame profile: it draws a frame's members as boxes ([Part IV, 4.3.1](/spec/0.4/compiler#4.3.1)). A truss layout's members have Swedish names ([Part IV, 7.4](/spec/0.4/compiler#7.4)), and its rooms are bounded otherwise in seven points, none of which made a difference on the rooms compared ([Part IV, 7.5](/spec/0.4/compiler#7.5))."
          },
          {
            "topic": "Drawings and assets",
            "text": "Its sheets are application records, and the SVG it draws is its screen's markup, which the SVG profile refuses; it issues drawings in Part XIV's files from those sheets. It keeps the PDFs it publishes outside the model, and its issued SVGs as kept files, not as assets ([Part XIV, 1.6](/spec/0.4/drawings#1.6); [Part XV, 11](/spec/0.4/assets#11))."
          },
          {
            "topic": "Commands in an envelope",
            "text": "Implements none of Part XVII yet: its commands carry no id, and 14 of its 91 kinds take no precondition ([Part XVII, 13](/spec/0.4/envelope#13))."
          },
          {
            "topic": "Prints",
            "text": "Its IFC prints say neither which version they came from nor that they are prints ([Part XVIII, 7.2](/spec/0.4/review#7.2))."
          }
        ],
        "gapsMore": "Each with what the reference does today, and what it has met since: [Open questions, 2](/spec/0.4/open-questions#2).",
        "sources": [
          {
            "text": "Conformance, 3",
            "href": "/spec/0.4/conformance#3"
          },
          {
            "text": "Open questions, 2",
            "href": "/spec/0.4/open-questions#2"
          }
        ]
      },
      {
        "id": "openeik-tools",
        "name": "`@openeik/tools`",
        "what": "A library for apps and the `openeik` command, in the specification repository (`packages/openeik`). Written from the specification alone, with no dependencies. It reads and writes 0.1 to 0.4, and migrates a model of 0.1 to 0.2, one of 0.2 to 0.3 and one of 0.3 to 0.4. It is on npm from the public release, and installs from openeik.org until then ([Developers](/developers#start)).",
        "link": "/developers",
        "linkText": "Developers",
        "summary": "Its README claims the writer and compiler (core) classes of 0.1.0-draft, and states no claim to a class of 0.2 yet. It implements the reader, validator and command processor without claiming them.",
        "classes": [
          {
            "class": "writer",
            "state": "claimed in its README, for 0.1.0-draft"
          },
          {
            "class": "compiler",
            "state": "claimed in its README for 0.1.0-draft, for the class-A rules (compiler core)"
          },
          {
            "class": "reader",
            "state": "built and tested, with the whole-model check or without it, not claimed: that check leaves out two rules of Part II"
          },
          {
            "class": "validator",
            "state": "built and tested, not claimed: it leaves out two rules of Part II"
          },
          {
            "class": "command-processor",
            "state": "built and tested for the core record operations, not claimed"
          },
          {
            "class": "version-store",
            "state": "a client of a store: it keeps no versions of its own"
          },
          {
            "class": "bridge",
            "as": "IFC",
            "state": "built and tested for IFC4, not claimed"
          }
        ],
        "notes": [
          "An implementation claims a class only when it meets every requirement the class lists; its README says which it claims, which it implements without claiming, and why.",
          "It diffs, merges three ways, and clones, pushes and pulls with a store; its version trees of four test folders, the L-house among them, have the same roots as the reference implementation's ([Open questions, 2](/spec/0.4/open-questions#2)).",
          "Its tests are counted under [Tests](#tests)."
        ],
        "gapsTitle": "Limits its README states",
        "gaps": [
          {
            "topic": "Validator",
            "text": "Does not check the framing families' expression language and parameters ([Part II, 5.4](/spec/0.4/language#5.4)), or that a sheet section's sizes follow its profiled sheet ([Part II, 5.2](/spec/0.4/language#5.2)). The reader's and the command processor's whole-model checks leave out the same two rules."
          },
          {
            "topic": "Compiler",
            "text": "Derives the class-A rules of Part IV: wall joins, roof windows and the rest of its reference behaviour are not derived ([Part IV, 2](/spec/0.4/compiler#2))."
          },
          {
            "topic": "Commands",
            "text": "Refuses the documentation profile, the domain operations, and four cases of operations on placed copies that need a copy's elements worked out, which the specification does not define ([Part V, 2](/spec/0.4/commands#2))."
          }
        ],
        "sources": [
          {
            "text": "`packages/openeik/README.md`",
            "href": "/tools/0.4/README.md"
          },
          {
            "text": "`packages/openeik/test/`"
          }
        ]
      }
    ]
  },
  "add": {
    "eyebrow": "Add yours",
    "h2": [
      "Add an implementation,",
      "with the classes it claims."
    ],
    "text": "At launch, open an issue or a merge request at the specification repository. Name the version and the classes your implementation claims, as every claim does.",
    "repo": "https://gitlab.com/openeik/spec",
    "repoText": "gitlab.com/openeik/spec",
    "note": "The specification repository is public at launch."
  }
}
