The beta's seal: what the review of the DSL branch found, and what closes it¶
A source
This page is a source of edakit – a concept, a prompt or the rules of a session –, shown as it is in the repository. Read it as such; the guides say what edakit does.
Status 2026-11-03: concept, from the review of the branch claude/friendly-mccarthy-n4kt6y at 5ee220f against
main at 46ad6af, asked for by the owner the same day. The yardstick was the owner's word of decision 48 of
circuit-dsl-toolchain.md: the original form is the default without a word about the DSL,
every facet of the DSL works only in a project whose edakit.toml switches it on, the site has a top-level section
"Explorative DSL". Built the same day on the owner's word ("setze das … dokument um"): B.1 to B.6 on the branch
explorative-dsl-beta-fixes, five commits on the DSL branch's tip 5ee220f (1dd3e31 to 460a3e4) – the DSL
branch itself is another session's and unchanged; it takes them as a fast-forward. The decisions below taken as
recommended and confirmed by the owner the same day (decision 50 of circuit-dsl-toolchain.md). Left: the
fast-forward of the DSL branch – overtaken: on 2026-11-04 the branch went onto main on the owner's word as edakit
1.1.17 (#344), with main merged in (decision 51 of circuit-dsl-toolchain.md).
Why¶
Decision 49 describes the beta as built: [beta] dsl = true in edakit.toml switches the DSL on (edakit/beta.py),
without it the DSL's files, commands and keys are refused with one line, the help hides its actions, the catalog, the
handbook and edakit rules leave its codes out, the DSL's text is docs/dsl/. The review checked that against the
code, the tests, the site and a project without the switch – the same led-bar on main and on the branch, every
everyday command, byte for byte. Most of it holds; five things do not, and a sixth is a crash. They are small, each
one a line or two, but together they are the difference between "a project without the switch is main" and "almost".
What the review found¶
The checks the branch passes, for the record: pytest -q -n auto – 3532 passed on the branch, 3092 on main, the same
34 environment failures on both (no ngspice in the container, a font metric in schematic draw) and the same 34 with
main merged in; the bell's golden tests with BELL_ROOT, 19 passed; python -m edakit.catalog.handbook --write,
python -m edakit.lang.blocks --write and docs/catalog/build.py change nothing, on the branch and with main merged;
docs/pages.py and mkdocs build --strict green, the tab "Explorative DSL" between Reference and Inside edakit, the
beta notice on all six pages, no dead link; ruff check green; the VS Code extension compiles; the pull request's
checks version and paths pass with the fragment changes/claude-friendly-mccarthy-n4kt6y.md (patch, right by
changes/README.md: no project must act); git merge-tree against today's main has no conflict, nothing of main is
lost or overwritten. With the switch, convert --to circuit, check, graph json --check and --write, fmt,
derive, sysml, kerml, block add --set, the requirements notation, the language server's functions and a
variant with of ../ all work on led-bar. block list and block show are byte-equal to main although the block
JSON now carries params and derivations. No command writes before it refuses: HOOKED of edakit/scripts.py
has no graph or block action, and the refusal sits before check and block in edakit/cli.py.
The findings, the heaviest first. "Reproduced" means a command was run and the output seen.
- The DEF engine runs without the switch.
edakit/engines/__init__.py:74putsderiveinto the list of graph engines unconditionally. A JSON project without[beta]whose graph carries a keyderivations– written by hand, sinceblock add --setis refused – getsDEF.derive – derived values within their window: 1 warningfromedakit check, with a fix text that namesedakit block add --setand.circuit; main reports nothing for the same graph.docs/dsl/README.md:27says "no DEF" without the switch. Reproduced. - argparse's error messages name the DSL.
edakit/cli.py:124keepsfmt,derive,sysmlandkermlinchoicesofgraph's action,:138registerslspas a subcommand,:132gives--tothe choicecircuit; the metavar hides them in--helponly.edakit graph bogusanswers "invalid choice: 'bogus' (choose from 'show', 'json', 'convert', 'fmt', 'derive', 'sysml', 'kerml')",edakit boguslistslspand prints the whole metavar where main prints "argument command",edakit graph convert --to xnamescircuit.tests/test_beta.py:84holdsformat_help()only, not the error texts. Reproduced. edakit graphswallows surplus positional arguments.edakit/cli.py:384-390parses withparse_known_argsand appends every leftover without a dash toargs.files, for the sake ofgraph fmt --check A Bon Python 3.11 and 3.12.edakit graph show U1 extrais exit 2 "unrecognized arguments: extra" on main and exit 0 on the branch, showing U1 – a change for every project, switch or not. Reproduced.- Two messages name
.circuitwithout the switch.edakit/graph_form.py:151and:181: a JSON project without[beta]runningedakit graph json --checkreads "… checks the file beside a TOML or a .circuit graph". The only difference in the everyday commands' output between main and the branch. Reproduced. - The beta notice names the branch.
docs/dsl/README.md:4: "it lives on the branchclaude/friendly-mccarthy-n4kt6y". The site publishes the sentence; after a merge it is false, and a reader of the site is not helped by a branch name either way. beta.dsl_ofcrashes on an edakit.toml that is not UTF-8.edakit/beta.py:28catchesTOMLDecodeErrorandAttributeError, notUnicodeDecodeError: a file with a byte 0xFF makesedakit graph fmt FILEand every request of the language server raise instead of answering the refusal line. Reproduced. Otherwise the function is robust: a broken TOML,dsl = "true",dsl = 1,beta = 1, a missing file, a path without edakit.toml all give False; a nested project takes the nearest edakit.toml upward; a symlink is resolved and its target's project decides.- Three readers of the switch, two forms they disagree on.
edakit/config.py:945andedakit/beta.py:19read with tomllib,edakit/agreements.py:187-190with a regular expression, like the hook's other keys. Forbeta = { dsl = true }orbeta.dsl = truethe config anddsl_ofsay on, the session start says nothing. Reproduced; the same pattern askicad()there, so a note rather than a defect. - One link from the rest of the site into the tab.
evals/README.md:63describes the three DSL evals under "Inside edakit" and linksdocs/dsl/; nothing else outside the navigation points there, the concept pages link the concept, which is main's. The site's search indexes the DSL's pages like any other. Seen in the built site. - Small things, not reproduced. The docstring of
edakit/engines/project.py:5says SYNC.graph runs "beside a TOML or a .circuit graph", the code runs it withcfg.dslonly;edakit/catalog/handbook.py:136filters the commands by a substring of the metavar;config.DSL_DOCrepeatsbeta.DOC.
Two things the review met are decided, not findings: edakit graph fmt on a source of edakit's own block library
works from any project (edakit/beta.py:15,22; decision 49, "edakit's block sources always pass"), and
edakit explain DEF.derive answers by name (decision 49, "edakit explain naming them").
What to do¶
On the branch, one commit per step, add-feature's order – the test first, then the code, the handbook's and the DSL's
pages where they say what changes. Every step keeps tests/test_beta.py as the place that holds the side without the
switch. Sizes as in the plans: S a day or less.
- B.1 The DEF engine behind the switch (finding 1), S.
graph_findings(ctx)inedakit/engines/__init__.pytakesderiveonly when the context's config hasdsl– the context carries the config already for the profile; where it has none (Design.from_datain tests), the engine is off. A test intests/test_beta.py: a JSON graph with aderivationsrecord outside its window gives no finding without the switch and the DEF.derive warning with it.docs/dsl/README.mdkeeps "no DEF" and is then right. - B.2 The parser without the DSL's words (finding 2), S. The DSL's actions,
lspand--to circuitleave the parser'schoices:graph's action is checked in_main–show,json,convertfor every project, the four ofDSL_ACTIONSonly with the switch, else the one refusal line that names the switch, asgraph fmtanswers today;lspis a subcommand the parser does not know,_maintakesargv[0] == "lsp"before parsing;--tois a plain string checked inmain_convert. An unknown action or--tothen errors as on main, word for word. The handbook's generatedcommandsections stay as they are (handbook.commands()reads the subparsers;lspis no longer there to filter). The test holds the error texts:edakit graph bogus,edakit bogus,edakit graph convert --to xagainst main's wording, throughcli.mainandcapsys. - B.3 No surplus arguments on
graph(finding 3), S.parse_known_argsgoes;graph fmt's files become a positionalfileswithnargs="*"declared aftername– argparse on 3.11 and 3.12 fills them in order when--checkcomes first, which the fragment's second line then no longer has to promise – or, where that breaksgraph show NAME,fmtparses its own files fromargvin_mainbefore the parser sees them.edakit graph show U1 extrais exit 2 again; a test holds it, andtests/test_lang_fmt.pykeepsfmt --check A B. - B.4 The messages of a JSON project (finding 4), S. The two sentences in
edakit/graph_form.pyname "a TOML graph" as on main; the.circuithalf of each goes into a sentence that is printed only when the project has the switch, or is dropped –docs/dsl/README.mdsays it already. The test runsgraph json --checkand--writeon a JSON project without the switch and compares with main's wording. - B.5 The crash and the notice (findings 5 and 6), S.
dsl_ofcatchesUnicodeDecodeErrorandOSErrorwith the rest and answers False; a test with a file of invalid bytes. The beta notice ofdocs/dsl/README.md– and the one every page ofdocs/dsl/repeats – names no branch: "not part of the released edakit, switched on per project, its form may change" is enough; a reader who wants the branch finds it in decision 48. - B.6 The notes (findings 7 to 9), S, optional.
agreements.dsl()may stay a regular expression, as the hook's other keys are; the two spellings it misses are worth one line indocs/dsl/README.md("as a table[beta]") or nothing. The sentence on the DSL's evals inevals/README.mdkeeps its link – a source names what it covers – or loses it, the owner's call. The docstring ofengines/project.pysays "with the switch";DSL_DOCreads frombeta.DOC.
After B.1 to B.5 the review's sentence turns: a project without the switch is main – the same output for every
command, error texts included –, and with the switch everything the branch built works. The branch stays a branch
until the owner asks for its pull request (decision 48); the steps are its own commits, no fragment line changes
(patch stays).
Decisions¶
Taken on 2026-11-03 as recommended, while building, and confirmed by the owner the same day:
- DEF without the switch (B.1): off without the switch – it is what decision 49 and
docs/dsl/README.mdsay; the alternative was on for every project, since aderivationskey reaches a JSON graph only by hand. - The link from the evals' README (B.6): kept – the evals are a source behind "Inside edakit", and their page says what it covers; the alternative was to cut it so that only the tab leads into the DSL.
- The branch name in the beta notice (B.5): dropped; the notice says how a project switches the DSL on.
As built¶
On explorative-dsl-beta-fixes, each step test first, tests/test_beta.py holding the side without the switch:
- B.1 (
1dd3e31):graph_findingsinedakit/engines/__init__.pyruns DEF only where the project's config hasdsl; without a project it does not run. - B.2, B.3 (
5289e66):build_parser(dsl=False)inedakit/cli.pyis main's parser word for word – no DSL action, nolsp, no--to,--out,--map,--set,--part.dsl_words(argv)opens the DSL's parser only for a command line that names one of them –lsp, a DSL action aftergraph, aftergraphorblock--to circuit,--to tomlor another of the options; the other commands' own--outstays theirs.dsl_used(args)names the command a project without the switch refuses. Onlygraph fmttakes files beyond its positionals (the 3.11 and 3.12 case of the fragment);graph show U1 extrais exit 2 again.handbook.commands()lists the parser's commands as on main. One way it differs from the plan of B.2: the DSL's parser keeps--toas a choice oftomlandcircuitinstead of a string checked inmain_convert–graph convert --to xnever reaches it, sincedsl_wordsopens it for those two values or another word of the DSL only. - B.4 (
e978861):graph_form.sources(cfg)– the two messages ofgraph jsonname "a TOML graph" as on main, "or a .circuit graph" with the switch. - B.5 (
649de4e): the notice of the six pages ofdocs/dsl/names the switch, not a branch, and a test holds it;beta.dsl_ofanswers False for an edakit.toml that cannot be read or is no UTF-8. - B.6 (
460a3e4): the session start reads[beta] dslwith tomllib where there is one – a table,beta.dsl = true, an inline table, as edakit.toml's check anddsl_ofread them –, the regular expression only without it;config.pytakes the DSL's page frombeta.DOC; the docstring ofengines/project.pysays "with the switch".
Checked on the branch: pytest -q -n auto 3545 passed, the same 34 environment failures as main (no ngspice, a font
metric); the bell's golden tests with BELL_ROOT 19 passed; handbook, block JSON and catalog generated without a
diff; mkdocs build --strict green; ruff check green. led-bar without the switch, against the main the branch last
merged (fe47cd3): version, check, graph json --check and --write, req, domains, gate, hook check,
rules, explain LIM.v, graph show, block add --dry-run and part lint byte for byte the same, and the errors
of edakit bogus, graph bogus, graph convert --to x and graph show U1 extra too; what differs is what decision
49 decides – the refusal line of a DSL command, edakit lsp and explain of the DSL's codes by name. With the switch
convert --to circuit, check, fmt --check A B, sysml, block add --set and graph json --check work.
Sources¶
- circuit-dsl-toolchain.md, decisions 48 and 49: the beta as decided and as built.
CLAUDE.md,docs/organisation.md,docs/concepts/done/versioning.mdandchanges/README.md: the rules the review read the branch against.- The review session of 2026-11-03 on the branch at
5ee220fand main at46ad6af: the commands above, each run on copies oftests/fixtures/led-barwith and without the switch, on main and on the branch, and the bell's clone fortests/test_lang_golden.py.