Contributing to EIS
LZX Industries maintains EIS and takes proposals from any maker or user of Eurorack hardware: open an issue or a pull request at git.lzxindustries.net/lzx/eurorack-specification.
What belongs in EIS
A requirement is a shall only where, without it, a conforming product from one maker could fail to fit, power up, or work with one from another (Scope 1.1). Construction choices, product functions, and factory procedures do not belong. A proposal for a new shall names the two products that would stop working together without it.
How a change is made
- Edit the model first.
data/requirements.jsonholds every requirement, with the role or interface it binds and how it is verified.data/document.jsonholds the document's structure: clauses, pages, prefixes, roles, interfaces, conditions, annexes, and data files. The otherdata/*.jsonfiles hold the numbers.tools/model.pyreads them all, and nothing else lists the document's structure. - Edit the clause prose in
spec/: it states the requirement and cites its identifier. - Run the generators and checks with
eis check(orpython -m pytest tests). The generators rewrite the register, the injected tables, and the figure cards; commit what they write. - If you touched prose, build the PDF and the site with
eis build all(needs thebuildextra andplaywright install chromium). Neither is committed; CI builds them.
Identifiers
Until the first edition is tagged, the register may be renumbered so that every prefix counts without a gap. From v0.1.0 on, identifiers are frozen:
- a new requirement takes the next free number of its prefix, whatever its place in the clause;
- a changed requirement keeps its identifier only when every product that met the old text meets the new one; otherwise it gets a new identifier;
- a requirement that EIS drops is deleted from the register, and its number is not reused. The register carries no dropped rows and no history.
data/register.lock.json records the identifiers and their text as last locked, and eis check fails on any change to them. An editor who changes the register deliberately rewrites the lock with python tools/model.py --lock.
Editions
An edition is a tag on this repository. pyproject.toml carries the version being drafted, and every claim example names draft until that version is tagged. A claim names one edition and stays valid for it. The foreword gives the edition, its status and date, and the terms of its review. The repository's history, not the text, records what an edition changed.
| Next edition | What it may change |
|---|---|
vX.Y.Z+1 |
Corrects errors only; nothing that conformed stops conforming. |
vX.Y+1.0 |
Adds requirements, signal classes, or formats; nothing that conformed to vX.Y stops conforming. |
vX+1.0.0 |
May remove or tighten a shall. |
Repository layout
| Folder | Holds |
|---|---|
spec/ |
The normative clauses, chapter 9 for the installer, and the front matter; requirements.md is generated |
annex/ |
The annexes; annex/README.md indexes them; every annex is informative |
figures/ |
Figure cards, 1920 px wide SVG, drawn by tools/ (and by the reference repository) in the house style of tools/card.py |
data/ |
Machine-readable models and the register |
tools/ |
Generators, the builders, and eis.py, the one entry point; tools/brand/ holds the fonts and mark the PDF embeds |
tests/ |
Checks against external publications and repository hygiene; fixtures/ holds the reduced timing contract |
pyproject.toml |
The version, pinned tooling, and the eis command (pip install -e ".[build,test]") |
standard.json |
Metadata for LZX Industries' standards registry; not part of the specification |
Third-party PDFs, drawings, and solid models are not stored here; data/sources.json records where each was retrieved and its checksum. The module survey and the catalog rail sections and inserts live in the eis-reference repository; EIS quotes two survey figures (5.2.2 and 5.4), and that repository's survey/summary.py --check fails if either quote goes stale.
Publishing
CI (.forgejo/workflows/checks.yml) runs eis check and eis build all on every push and pull request and keeps the PDF and the site as artifacts. A tag vX.Y.Z is an edition and a tag vX.Y.Z-rc.N a review candidate, which no claim names: for either, the same workflow then rebuilds the site with root-absolute links under /eis/ and uploads it, with the PDF, to web/v1/media/eis/ on the web CDN bucket, which the storefront serves at lzxindustries.net/eis. The deploy job reads four repository secrets, named as the monorepo's web CDN environment variables: LZX_WEB_CDN_S3_ENDPOINT_HOSTNAME, LZX_WEB_CDN_S3_BUCKET, LZX_WEB_CDN_S3_ACCESS_KEY_ID, and LZX_WEB_CDN_S3_SECRET_ACCESS_KEY. Nothing on a desk publishes an edition; lzx eis.publish.site in the monorepo is for previewing a draft at the same address between editions.
Style
- Plain English in short sentences. Numbers carry units, with a space before the unit and before %.
- A shall sentence names its identifier in parentheses, without the
EIS-prefix (PANEL-009); the register and the JSON carry the prefix. - There are no shoulds: a recommendation is written "EIS recommends …" and carries no identifier.
- The text describes EIS as it is. No page narrates how the text changed, keeps a change log, records a dropped requirement, or compares EIS with standards it does not reference; the VOICE lint in
tests/links.pyrefuses the words of change on every page. - Tables that mirror a
data/file are generated between marker comments, not typed. - One voice: Eurorack, American spelling (catalog, color, center, aluminum, analog), video sync written in full, and the Ω sign (75 Ω). The
VOICElist intests/links.pyis the rule and the test.