Packages
macula
11.2.0
15.0.0-rc.2
15.0.0-rc.1
14.10.0
14.9.0
14.8.2
14.8.1
14.8.0
14.7.0
14.6.0
14.5.0
14.4.0
14.3.0
14.2.1
14.2.0
14.1.0
14.0.0
13.6.0
13.5.0
13.4.0
13.3.0
13.2.2
13.2.1
13.2.0
13.1.0
13.0.1
13.0.0
12.12.0
12.11.1
12.11.0
12.10.0
12.9.1
12.9.0
12.8.0
12.7.0
12.6.0
12.5.1
12.5.0
12.4.0
12.3.0
12.2.1
12.2.0
12.1.0
12.0.0
11.5.0
11.4.0
11.3.1
11.3.0
11.2.0
11.1.0
11.0.0
10.25.0
10.24.0
10.23.0
10.22.0
10.21.0
10.20.3
10.20.2
10.20.0
10.19.2
10.19.1
10.19.0
10.18.0
10.17.0
10.16.0
10.15.0
10.14.5
10.14.4
10.14.2
10.14.1
10.14.0
10.13.2
10.13.1
10.11.0
10.10.2
10.10.1
10.10.0
10.9.1
10.9.0
10.8.0
10.7.0
10.5.8
10.5.7
10.5.6
10.5.5
10.5.4
10.5.3
10.5.2
10.5.1
10.5.0
10.4.0
10.2.0
10.1.1
10.1.0
10.0.2
10.0.1
10.0.0
9.13.8
9.8.2
9.8.1
9.8.0
9.5.0
9.4.0
9.3.1
9.3.0
9.2.0
9.1.1
9.1.0
9.0.0
8.7.0
8.6.0
8.5.0
8.4.1
8.4.0
8.3.0
8.2.0
8.1.0
8.0.2
8.0.1
8.0.0
7.1.0
7.0.0
6.0.0
5.2.2
5.2.1
5.2.0
5.1.0
5.0.0
4.8.0
4.7.1
4.7.0
4.6.0
4.5.0
4.4.10
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.1
4.3.0
4.2.9
4.2.8
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.16.0
3.15.3
3.15.2
3.15.1
3.14.0
3.13.0
3.12.1
3.12.0
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.9.0
3.8.0
3.7.0
3.5.0
3.4.0
3.3.0
3.2.0
3.1.0
3.0.0
2.1.1
2.1.0
2.0.0
1.5.2
1.5.1
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.19
1.4.18
1.4.17
1.4.16
1.4.15
1.4.14
1.4.13
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.2.0
1.1.0
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.48.6
0.48.5
0.48.4
0.48.3
0.48.2
0.48.1
0.48.0
0.47.1
0.47.0
0.46.3
0.46.1
0.46.0
0.45.3
0.45.2
0.45.1
0.45.0
0.44.2
0.44.1
0.44.0
0.43.3
0.43.2
0.43.1
0.43.0
0.42.9
0.42.8
0.42.7
0.42.6
0.42.5
0.42.4
0.42.3
0.42.2
0.42.1
0.42.0
0.41.1
0.41.0
0.40.1
0.40.0
0.39.9
0.39.8
0.39.7
0.39.6
0.39.5
0.39.4
0.39.3
0.39.2
0.39.1
0.39.0
0.38.8
0.38.7
0.38.6
0.38.5
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.7
0.37.6
0.37.5
0.37.4
0.37.3
0.37.2
0.37.1
0.37.0
0.36.6
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.1
0.34.0
0.33.1
0.33.0
0.32.5
0.32.4
0.32.3
0.32.2
0.32.1
0.32.0
0.31.9
0.31.8
0.31.7
0.31.6
0.31.5
0.31.4
0.31.3
0.31.2
0.31.1
0.31.0
0.30.10
0.30.9
0.30.8
0.30.7
0.30.6
0.30.5
0.30.4
0.30.3
0.30.2
0.30.1
0.30.0
0.29.0
0.28.3
0.28.2
0.28.1
0.28.0
0.27.1
0.27.0
0.26.1
0.26.0
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.6
0.24.5
0.24.4
0.24.3
0.24.2
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.7
0.21.6
0.21.5
0.21.4
0.21.2
0.21.1
0.21.0
0.20.25
0.20.24
0.20.23
0.20.22
0.20.21
0.20.20
0.20.19
0.20.18
0.20.17
0.20.16
0.20.15
0.20.14
0.20.13
0.20.12
0.20.11
0.20.10
0.20.9
0.20.8
0.20.7
0.20.6
0.20.5
0.20.3
0.20.2
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.12.6
0.12.5
0.12.3
0.11.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.30
0.7.29
0.7.28
0.7.27
0.7.26
0.7.25
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
Macula HTTP/3 Mesh SDK — connect, subscribe, publish, call, advertise
Current section
Files
Jump to
Current section
Files
rebar.config
%% -*- mode: erlang -*-
%% Macula HTTP/3 Mesh - Root Rebar3 Configuration
{erl_opts, [
debug_info,
warnings_as_errors,
warn_export_vars,
warn_unused_vars,
warn_obsolete_guard
]}.
%% Include subdirectories in src/ for compilation. Each slice
%% directory holds modules for a coherent capability — see
%% PLAN_V2_PARITY § 3 for the layout rationale. Foundational
%% primitives (macula_id, macula_realm, macula_topic, etc.) stay
%% flat at src/ root; capability slices live in subdirs.
{src_dirs, [
"src",
"src/auth",
"src/client",
"src/identity",
"src/macula_cert_system",
"src/macula_cluster_system",
"src/macula_dist_system",
"src/macula_yggdrasil",
"src/mri",
"src/observability",
"src/overlay",
"src/peering",
"src/pubsub",
"src/record",
"src/v1"
]}.
{pre_hooks, [
{compile, "sh -c 'B=\"${REBAR_DEPS_DIR}/macula\"; [ -f \"$B/priv/build-nifs.sh\" ] || B=\".\"; sh \"$B/priv/build-nifs.sh\" \"$B\"'"}
]}.
{deps, [
%% QUIC transport: Quinn via Rust NIF (replaces quicer/MsQuic)
%% Built from native/macula_quic/ via cargo pre_hooks above
%% MessagePack serialization
%% (msgpack removed in v3.0.0 — wire protocol switched to CBOR
%% via macula_cbor / macula_cbor_nif Rust NIF. The `msgpack` atom
%% seen elsewhere in this codebase, e.g. macula_stream's
%% encoding()/raw|msgpack type, is just a symbolic tag callers can
%% pass through — it never required the msgpack library itself.
%% A stale local rebar.lock kept resolving the msgpack package
%% anyway, for one dead test file (removed 2026-09-05); every hex
%% release since v3.0.0 silently carried it as a phantom runtime
%% requirement as a result. Loose `~>` constraints below per
%% policy — exact pins block coordinated dep resolution.
%% Process registry
{gproc, "~> 1.3"},
%% Telemetry for observability and metrics
{telemetry, "~> 1.3"}
%% JSON encoding: Using built-in json module (OTP 27+)
%% Crypto, UCAN, DID, MRI NIFs: Built from native/ via Rust/Cargo
%% (absorbed from macula-nifs package in v1.0)
%% Falls back to pure Erlang when Rust toolchain not available
%% Note: Ra/Raft was removed in v0.14.0
%% Macula uses CRDTs (macula_crdt.erl) for masterless state management
]}.
{project_plugins, [
rebar3_hex,
rebar3_proper,
rebar3_ex_doc
]}.
%% Test configuration
{eunit_opts, [
verbose,
%% The macula application refuses to start without a crypto profile.
{sys_config, "config/test.sys.config"}
]}.
{cover_enabled, true}.
{cover_opts, [verbose]}.
{cover_excl_mods, []}. %% Modules to exclude from coverage (e.g., generated code)
{cover_print_enabled, true}.
{cover_export_enabled, true}.
{ct_opts, [
{sys_config, "config/test.sys.config"}
]}.
%% xref fails on what is a defect in a library: a call to a function that does
%% not exist, a function that does not exist, a local function nothing calls,
%% and a deprecated call. rebar3's default also checks exports_not_used, which
%% reports the functions a library exports for its consumers to call.
{xref_checks, [
undefined_function_calls,
undefined_functions,
locals_not_used,
deprecated_function_calls,
deprecated_functions
]}.
{dialyzer, [
{warnings, [
no_return,
no_unused,
no_improper_lists,
no_fun_app,
no_match,
no_opaque,
no_fail_call,
error_handling
]},
{plt_apps, top_level_deps},
{plt_location, local},
{base_plt_apps, [erts, kernel, stdlib, crypto, public_key, ssl]},
{base_plt_location, global}
]}.
%% Shell configuration
{shell, [
{apps, [macula]},
{config, "config/sys.config"}
]}.
%% Release configuration
{relx, [
{release, {macula, "3.0.0"}, [
macula,
sasl,
runtime_tools
%% observer - removed for headless deployments (requires wx/OpenGL)
]},
{mode, dev},
{include_erts, true},
{extended_start_script, true},
{sys_config, "./config/sys.config"},
{vm_args, "./config/vm.args"},
{overlay, [
{mkdir, "log"},
{mkdir, "data"},
{copy, "README.md", "README.md"},
{copy, "LICENSE", "LICENSE"}
]}
]}.
%% Profiles
{profiles, [
{test, [
{deps, [
{proper, "1.4.0"},
{meck, "0.9.2"}
]},
%% Tests may use the deprecated `catch' expression where the
%% semantics (catch-anything, return the error term) is exactly
%% what a teardown wants; OTP 28 warns on it and warnings_as_errors
%% would fail any fresh test-profile compile (meck's own matcher
%% uses it too). Relaxed for tests only, like nowarn_export_all.
{erl_opts, [nowarn_export_all, nowarn_deprecated_catch]},
%% rebar3 compiles an extra source directory recursively: test covers its
%% subdirectories, so each test module compiles once, into
%% _build/test/lib/macula/test. Listing a subdirectory as well compiles its
%% modules a second time, into a directory of their own.
{extra_src_dirs, [
"test",
"bench"
]}
]},
%% relx-only, deliberately no erl_opts: rebar3 merges a fetched
%% dependency's erl_opts across EVERY profile it defines, not just
%% whichever one the consumer actually activated (confirmed live
%% 2026-09-05 with a controlled A/B rebuild -- a bare git dependency
%% fetch of this exact repo with vs. without this profile's
%% erl_opts was the only variable that changed). `no_debug_info' /
%% `deterministic' here used to strip debug_info from every
%% consumer's copy of macula unconditionally, whether or not THEY
%% ever selected `prod' -- silently breaking `rebar3 dialyzer
%% --plt-extra-apps macula' for anyone who depends on this library.
%% Nothing in this repo's own CI/scripts invokes `rebar3 as prod'
%% or a relx release build (grepped, zero hits) -- this profile's
%% `relx' block is a local-dev-only convenience for running a
%% leaner standalone macula node, and dropping debug_info from that
%% one local artifact was never worth breaking every consumer's
%% dialyzer. If a leaner local build is wanted again, pass
%% `--erl_opts +no_debug_info' on the `rebar3 as prod release'
%% command line instead of putting it back here.
{prod, [
{relx, [
{mode, prod},
{dev_mode, false},
{include_src, false}
]}
]},
{lint, [
{plugins, [
{rebar3_lint, "5.0.4"}
]}
]}
]}.
%% Elvis style rules — shared macula_min ruleset (mirrors evoq/reckon-db).
%% Targets deep nesting, nested try/catch, if-expressions. Run `rebar3 lint`.
{elvis, [
{rulesets, #{
macula_min => [
{elvis_style, no_deep_nesting, #{level => 2}},
{elvis_style, no_nested_try_catch, #{}},
{elvis_style, no_if_expression, #{}}
]
}},
{config, [
#{files => ["src/**/*.erl"], ruleset => macula_min}
]}
]}.
%% Documentation
{ex_doc, [
%% Historical CHANGELOG entries name functions that are hidden or
%% private today, and link the unrendered CHANGELOG_LEGACY.md.
%% Rewriting past entries to please the link checker would change
%% what was written at the time, so those references are not
%% checked in that one file.
{skip_undefined_reference_warnings_on, ["CHANGELOG.md"]},
{extras, [
{"README.md", #{title => "Overview"}},
{"CHANGELOG.md", #{title => "Changelog"}},
%% CHANGELOG_LEGACY.md (pre-3.0) is shipped in the hex package
%% but intentionally NOT rendered in ex_doc — legacy entries
%% predate the 3.0 wire-format cutover and use EDoc-style
%% formatting that doesn't round-trip cleanly through ex_doc's
%% Markdown parser. View the raw file on GitHub if you need
%% pre-3.0 history.
{"LICENSE", #{title => "License"}},
{"docs/GLOSSARY.md", #{title => "Glossary"}},
%% SDK Guides — daemon-facing (supervised wrappers)
{"docs/guides/rpc/RPC_GUIDE.md", #{title => "RPC Guide"}},
{"docs/guides/rpc/RPC_PROTOCOL.md", #{title => "RPC Protocol"}},
{"docs/guides/pubsub/PUBSUB_GUIDE.md", #{title => "PubSub Guide"}},
{"docs/guides/pubsub/PUBSUB_PROTOCOL.md", #{title => "PubSub Protocol"}},
{"docs/guides/content/CONTENT_GUIDE.md", #{title => "Content Guide"}},
{"docs/guides/content/CONTENT_PROTOCOL.md", #{title => "Content Protocol"}},
{"docs/guides/streaming/STREAMING_GUIDE.md", #{title => "Streaming Guide"}},
{"docs/guides/streaming/STREAMING_PROTOCOL.md", #{title => "Streaming Protocol"}},
%% Shared — cross-cutting, needed regardless of which primitive pair
{"docs/guides/shared/CONNECTING_GUIDE.md", #{title => "Connecting"}},
{"docs/guides/shared/TOPIC_NAMING_GUIDE.md", #{title => "Topic Naming Convention"}},
{"docs/guides/shared/AUTHORIZATION_GUIDE.md", #{title => "Authorization (UCAN/DID)"}},
{"docs/guides/shared/MRI_GUIDE.md", #{title => "MRI (Resource Identifiers)"}},
{"docs/guides/shared/RECORDS_GUIDE.md", #{title => "Records Guide"}},
%% Separate capability axis — not primitive-pair-shared
{"docs/guides/DIST_OVER_MESH_GUIDE.md", #{title => "Distribution Over Mesh"}},
{"docs/guides/CLUSTERING_GUIDE.md", #{title => "Clustering"}},
{"docs/guides/DEVELOPMENT.md", #{title => "Development Guide"}},
%% Overlay — realm-scoped membership + gossip, absorbed from the
%% standalone macula-hyparview/macula-plumtree packages in 10.4.0.
%% No supervised OTP wrapper exists yet (unlike RPC/PubSub/Content/
%% Streaming), so each guide covers both the "why" and the raw API.
{"docs/guides/overlay/HYPARVIEW_GUIDE.md", #{title => "HyParView Guide"}},
{"docs/guides/overlay/PLUMTREE_GUIDE.md", #{title => "Plumtree Guide"}}
]},
{main, "readme"},
{source_url, "https://github.com/macula-io/macula"},
{assets, #{"assets" => "assets"}},
{logo, "artwork/logo.svg"},
{prefix_ref_vsn_with_v, false},
%% Mirrors groups_for_modules: the daemon-facing Guide for each
%% primitive pair groups separately from its raw-primitive Protocol
%% doc, so the hexdocs sidebar screams "start here" vs. "raw wire
%% internals" the same way it already screams "Supervised Wrappers"
%% vs. everything else below. Cross-cutting guides get their own
%% group; DIST_OVER_MESH/CLUSTERING/DEVELOPMENT stay in ex_doc's
%% default ungrouped bucket — not primitive-pair material, no group
%% pulls its own weight yet.
{groups_for_extras, [
{"Guides", [
<<"docs/guides/rpc/RPC_GUIDE.md">>,
<<"docs/guides/pubsub/PUBSUB_GUIDE.md">>,
<<"docs/guides/content/CONTENT_GUIDE.md">>,
<<"docs/guides/streaming/STREAMING_GUIDE.md">>
]},
{"Protocols", [
<<"docs/guides/rpc/RPC_PROTOCOL.md">>,
<<"docs/guides/pubsub/PUBSUB_PROTOCOL.md">>,
<<"docs/guides/content/CONTENT_PROTOCOL.md">>,
<<"docs/guides/streaming/STREAMING_PROTOCOL.md">>
]},
{"Shared Guides", [
<<"docs/guides/shared/CONNECTING_GUIDE.md">>,
<<"docs/guides/shared/TOPIC_NAMING_GUIDE.md">>,
<<"docs/guides/shared/AUTHORIZATION_GUIDE.md">>,
<<"docs/guides/shared/MRI_GUIDE.md">>,
<<"docs/guides/shared/RECORDS_GUIDE.md">>
]},
{"Overlay Guides", [
<<"docs/guides/overlay/HYPARVIEW_GUIDE.md">>,
<<"docs/guides/overlay/PLUMTREE_GUIDE.md">>
]}
]},
%% Surfaces the 5 supervised OTP-behaviour primitive pairs as a
%% distinct hexdocs sidebar group, ahead of the raw wire-protocol
%% modules (macula_client, macula_station_link, macula_stream,
%% macula_quic, ...) an application almost never touches directly.
%% These are what "Devs will use" (the design question that
%% prompted this) — everything else stays in ex_doc's default
%% ungrouped bucket rather than hand-maintaining a second group
%% that would just drift as modules are added.
{groups_for_modules, [
{"Supervised Wrappers", [
macula_request, macula_response,
macula_publisher, macula_subscriber,
macula_feeder, macula_download,
macula_pusher, macula_upload,
macula_streamer, macula_stream_sink
]},
%% Realm-scoped membership + gossip, absorbed from macula-hyparview/
%% macula-plumtree in 10.4.0. hecate_* names are kept as-is —
%% macula-station already calls them by these exact names.
{"Overlay (HyParView + Plumtree)", [
macula_hyparview_view, macula_hyparview_proto, macula_hyparview_endorsement,
hecate_plumtree, hecate_pubsub, hecate_pubsub_server,
hecate_pubsub_registry, hecate_or_set
]}
]}
]}.
%% Hex package configuration
{hex, [
{doc, #{provider => ex_doc}},
{licenses, ["Apache-2.0"]},
{links, #{
<<"GitHub">> => <<"https://github.com/macula-io/macula">>,
<<"Documentation">> => <<"https://hexdocs.pm/macula">>,
<<"Changelog">> => <<"https://github.com/macula-io/macula/blob/main/CHANGELOG.md">>
}},
{description, "Macula HTTP/3 Mesh SDK — connect to relay mesh, pub/sub, RPC, Erlang distribution over QUIC, identity (Ed25519/UCAN/DID), MRI resource identifiers"},
%% Kept equal to the `files' list in src/macula.app.src, which is the
%% list rebar3_hex packages.
{files, [
"src",
"include",
"priv",
"native/macula_quic/Cargo.toml",
"native/macula_quic/Cargo.lock",
"native/macula_quic/src",
"native/macula_crypto_nif/Cargo.toml",
"native/macula_crypto_nif/Cargo.lock",
"native/macula_crypto_nif/src",
"native/macula_ucan_nif/Cargo.toml",
"native/macula_ucan_nif/Cargo.lock",
"native/macula_ucan_nif/src",
"native/macula_did_nif/Cargo.toml",
"native/macula_did_nif/Cargo.lock",
"native/macula_did_nif/src",
"native/macula_mri_nif/Cargo.toml",
"native/macula_mri_nif/Cargo.lock",
"native/macula_mri_nif/src",
"native/macula_cbor_nif/Cargo.toml",
"native/macula_cbor_nif/Cargo.lock",
"native/macula_cbor_nif/src",
"rebar.config",
"rebar.lock",
"README.md",
"CHANGELOG.md",
"CHANGELOG_LEGACY.md",
"LICENSE",
"CONTRIBUTING.md",
"CODE_OF_CONDUCT.md"
]}
]}.