Contract Boundary Spec

Summary

Libero owns the typed wire-contract artifacts for values selected by a framework. The framework supplies type seeds. Libero walks the reachable custom type graph and generates protocol-facing code that must agree across BEAM, JavaScript, ETF, JSON, and contract artifacts.

Libero does not own handler discovery, dispatch, routing, request correlation, WebSocket lifecycle, SSR composition, hydration, broadcast delivery, or app state. Rally owns those layers.

Ownership

Libero owns:

Frameworks own:

The short rule: framework code decides what crosses the boundary and when. Libero decides how those typed values become protocol data and back.

Consumer API Shape

Rally-style consumers call the top-level library API:

let assert Ok(discovered) = libero.walk(seeds)
let atoms = libero.generate_atoms(discovered:, atoms_module:, wire_module:)
let assert Ok(wire) = libero.generate_wire_erl(discovered:, wire_module:)
let decoders_js =
  libero.generate_decoders_ffi(discovered:, package:, dependency_packages:)
let decoders_gleam = libero.generate_decoders_gleam()
let etf = libero.generate_etf_codec_module(atoms_module:, decoders_module:)
let contract =
  libero.generate_json_contract(discovered:, push_types:, ssr_models:)

The functions return strings. Frameworks own file I/O and generated module layout.

Runtime Helpers

ETF helpers live in libero/etf/wire. JSON helpers live in libero/json/wire. The generated ETF module from generate_etf_codec_module exposes only ensure, encode, and decode, which is the surface Rally’s generated protocol modules use. The lower-level runtime helper names describe protocol concepts used by the codec runtimes and tests:

ConceptHelper
Encode an outbound request envelopeencode_request
Decode an inbound request envelopedecode_request
Encode a response frameencode_response
Decode a server framedecode_server_frame
Encode a push frameencode_push
Encode SSR flagsencode_flags
Decode SSR flagsdecode_flags_typed

Rally-generated modules own request ids, result envelopes, frame tags, and page dispatch around the generated codec module. Application code should not inspect ETF frame bytes, assemble JSON envelopes by hand, or call raw wire-transformer functions for normal traffic.

Generated Modules

The supported generated artifact set is:

Frameworks may generate their own request/result/push facade around those artifacts. Libero should not generate framework-specific app glue.

Security Model

The protocol boundary is where malformed input becomes typed data. Libero should make that boundary auditable.

The boundary should enforce:

The caller should receive structured protocol errors. Consumers should not parse codec exception strings.

Acceptance Criteria

Search Document