Skip to content

dizzy.generators.wiring

dizzy.generators.wiring

Wiring generator — lib//wiring/, the binding from elements to the runtime.

This is the last artifact that used to be copied out of the feature-file by hand. The feat already declares, per element, exactly the argument list of its generated context: a procedure's command: gives what it registers under, emits: the emitter bindings, queries: the query bindings, environment:/telemetry: the rest; a projection's event: gives the event->projection routing; a policy's event:/emits: give its registration and its dispatch targets. Every line of a hand-written wiring is that one template repeated, which makes it a pure function of the feat — so it is generated, and cannot drift.

What is emitted is engine-mediated: emitters go to engine.emit_event and a policy's dispatch to engine.dispatch_command, never to another element. The engine then owns the ordering rule (projections fold and the read model commits before policies dispatch) rather than each handler restating it.

WIRING_PACKAGE = 'wiring' module-attribute

Workspace member name, and the importable module (from wiring import ...).

feat_name(feat_file_name)

recipes.feat.yaml -> recipes. The feature's name is its file's.

Source code in dizzy/src/dizzy/generators/wiring.py
528
529
530
def feat_name(feat_file_name: str) -> str:
    """``recipes.feat.yaml`` -> ``recipes``. The feature's name is its file's."""
    return feat_file_name.split(".")[0]

render_wiring(feat, feat_file='feature.feat.yaml')

Render lib//wiring/src/wiring.py for feat.

Source code in dizzy/src/dizzy/generators/wiring.py
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
def render_wiring(feat: FeatureDefinition, feat_file: str = "feature.feat.yaml") -> str:
    """Render lib/<runtime>/wiring/src/wiring.py for *feat*."""
    example = next(
        (e.name for e in list(feat.procedures or []) + list(feat.projections or [])),
        "element_name",
    )
    preamble = _PREAMBLE.format(
        feat_name=feat_name(feat_file), feat_file=feat_file, example=example
    )
    blocks = [
        preamble,
        "\n".join(_render_imports(feat)),
        "\n".join(_render_resources(feat)),
        "\n".join(_render_queries(feat)),
        "\n".join(_render_projection_runners(feat)),
        "\n".join(_render_build_engine(feat)),
        "\n".join(_render_host(feat_file)),
    ]
    return "\n\n".join(block.rstrip() for block in blocks) + "\n"

render_wiring_pyproject_toml(feat)

The wiring package manifest.

This is the one generated package that depends on DIZZY itself: the elements import only their contracts, but the wiring imports dizzy.engine — it is what binds them to a runtime.

The dizzy requirement is deliberately left un-sourced here. DIZZY is not published to a package index, so it needs a source — but that belongs at the workspace ROOT (see render_workspace_pyproject_toml), where it applies to every member and can be pointed at a checkout or a git URL without rewriting this file. Keeping it out means this manifest is the same wherever the lib is shipped.

Source code in dizzy/src/dizzy/generators/wiring.py
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
def render_wiring_pyproject_toml(feat: FeatureDefinition) -> str:
    """The wiring package manifest.

    This is the one generated package that depends on DIZZY itself: the elements
    import only their contracts, but the wiring imports ``dizzy.engine`` — it is
    what binds them to a runtime.

    The ``dizzy`` requirement is deliberately left un-sourced here. DIZZY is not
    published to a package index, so it needs a source — but that belongs at the
    workspace ROOT (see ``render_workspace_pyproject_toml``), where it applies to
    every member and can be pointed at a checkout or a git URL without rewriting
    this file. Keeping it out means this manifest is the same wherever the lib is
    shipped.
    """
    elements = (
        [("procedure", p.name) for p in feat.procedures or []]
        + [("policy", p.name) for p in feat.policies or []]
        + [("projection", p.name) for p in feat.projections or []]
        + [("query", q.name) for q in feat.queries or []]
    )
    deps = ['    "dizzy",', '    "gen_def",', '    "gen_int",'] + [
        f'    "{kind}-{name}",' for kind, name in elements
    ]
    sources = [
        "gen_def = { workspace = true }",
        "gen_int = { workspace = true }",
    ] + [f"{kind}-{name} = {{ workspace = true }}" for kind, name in elements]
    return "\n".join(
        [
            "[project]",
            'name = "wiring"',
            'version = "0.1.0"',
            'requires-python = ">=3.11"',
            "dependencies = [",
            *deps,
            "]",
            "",
            "[tool.uv.sources]",
            *sources,
            "",
            "[build-system]",
            'requires = ["hatchling"]',
            'build-backend = "hatchling.build"',
            "",
            "[tool.hatch.build.targets.wheel]",
            'sources = ["src"]',
            'include = ["src/wiring.py", "src/*.feat.yaml"]',
            "",
        ]
    )

write_wiring_python_uv(feat, feat_file, output_dir)

Write lib/python-uv/wiring/ — always overwritten, like every generated interface.

Source code in dizzy/src/dizzy/generators/wiring.py
606
607
608
609
610
611
612
613
614
615
def write_wiring_python_uv(feat: FeatureDefinition, feat_file: Path, output_dir: Path) -> None:
    """Write lib/python-uv/wiring/ — always overwritten, like every generated interface."""
    base = output_dir / "lib" / "python-uv" / WIRING_PACKAGE
    (base / "src").mkdir(parents=True, exist_ok=True)
    (base / "pyproject.toml").write_text(render_wiring_pyproject_toml(feat))
    (base / "src" / "wiring.py").write_text(render_wiring(feat, feat_file.name))
    # The feat travels with the package so a lifted-out lib/ can still read its
    # own topology; it is regenerated here, never edited in place.
    (base / "src" / feat_file.name).write_text(feat_file.read_text())
    logger.debug("wrote wiring package", extra={"path": str(base)})