Code generation that can prove what it made, and a test harness that tries to break it.
Ferris bakes macaroons here. Every batch starts from a written recipe, every tray is checked against that recipe before it leaves the oven, and a taste tester with no loyalty to the baker gets the first bite.
Macroonz knows nothing about your domain. Your types, your errors, your identities, your bounds — all yours. It only knows how to bake exactly what you asked for, and how to find out whether it's any good.
Writing a derive macro means parsing a token stream, emitting another one, and hoping. Nobody can say afterwards what was generated, why, or what would change it. Testing a library means writing the examples you thought of. The bug is in the one you didn't.
Macroonz replaces both hopes with records.
| You have | You get |
|---|---|
| A derive that emits tokens | An expansion that names every unit it produced, proves the set matches its plan, and explains each decision — before a byte reaches rustc |
| A handful of example tests | Generated inputs, injected faults, a controlled clock, mutants of your own code, and the reproduction material each road earns — generation keeps its seed when generation drove the run, reduction mints the smallest witness it reached, and the replay capsule carries it |
One storefront opens onto the oven, the hand that loads it, and the taste tester without pouring their vocabularies into one bowl.
| Crate | Directory | What it is |
|---|---|---|
macroonz |
/ |
The storefront exposing the one recipe! workflow entrance while preserving the expert owners as compiler, macros, and feature-gated harness modules; this is the crate you add. |
macroonz-compiler |
macros/compiler/ |
The ordinary callable compiler that informs structural declarations, projects requested ordinary Rust or evidence material, then plans, renders, closes, explains, binds, and emits. |
macroonz-macros |
macros/proc/ |
The grammar-free procedural host carrying the recipe entrance and built-in declarations through compiler-owned doors with token conversion, span custody, diagnostic placement, and emission. |
macroonz-harness |
harness/ |
The judge. Descriptors, generation, properties, oracles, faults, corpus, fuzz composition, mutation, benches, reports, replay. The default storefront includes it; the diet posture removes it from a shipping graph. |
flowchart LR
accTitle: Macroonz package dependencies
accDescr: The macroonz facade depends on the compiler and procedural macro crates, the procedural macro crate also depends on the compiler, and the optional harness feature adds the harness crate.
YOU["your crate"] --> F["macroonz"]
F --> C["macroonz-compiler"]
F --> PROC["macroonz-macros"]
PROC --> C
F -. harness feature .-> H["macroonz-harness"]
Arrows point at dependencies. The compiler depends on nothing in this workspace. The proc crate reaches the harness only from its tests, and the harness reaches the compiler only from its tests.
macroonz::recipe! is the one workflow entrance for declaring ordinary Rust ingredients, structural relationships and postures, effects, and requested projections.
The recipe vocabulary describes only the structure Macroonz must account over; complete authored Rust items remain authored Rust rather than becoming a parallel framework AST.
You own every name, item, vocabulary, relation, effect, policy, lawful answer, exact Rust fragment, requested projection, and independent behavioral claim. Macroonz owns bounded capture, structural informing, exact accounting, mechanical projection, and the generation road that proves the requested output set was delivered whole. Rustc remains the authority for paths, visibility, types, ownership, borrowing, lifetimes, coherence, exhaustiveness, const evaluation, and the final legality of the emitted Rust.
An ordinary Rust path is enough when Macroonz only needs to refer to a type, trait, function, effect, constructor, constant, module, associated item, or earlier generated item. An explicit roster is required only when Macroonz must enumerate members or prove that every member received one disposition.
Authored items remain where they were written.
Generated companions remain inside the recipe module, private support remains in one hidden child, and public names, visibility, destinations, reexports, and unsafe boundaries remain explicit caller choices.
Within one recipe, Macroonz preflights every generated name it can derive from the declaration in the Rust namespace where that name will live: the baked module, companion constants and dispatch functions, relation-table and evidence modules, codec and transition refusal types, typestate, and an explicitly addressed support macro.
A collision inside that declared universe refuses the request before partial output, while imports, glob results, downstream macro output, and names generated by another recipe invocation remain ordinary rustc name-resolution authority.
No ambient scan or cross-recipe registry is performed, and no ordinary generated item is sprayed into the crate root or reexported automatically.
An evidence bake may carry an explicitly named support macro because Rust exports such macros at the declaring crate root.
That caller-authored address is the exception rather than an automatic reexport: its cargo stays inert until the external test or bench target invokes it with the declaring-crate path.
The root macroonz::support! entrance selects the facade's harness gate; the explicit carrier entrance also accepts a target-selected gate path.
The compiler's recipe home owns the exact contract for declaration_conformance; and compile_contract;.
Use a caller-authored harness property, oracle, or model comparison when judgment must be independent of the declaration.
The generic shape is ordinary Rust plus only the accounts a projection needs:
macroonz::recipe! {
pub mod access {
pub enum Stage { Draft, Published }
pub enum Capability { Read, Write }
bake! {
vocabularies { Stage; Capability; };
relations {
policy(Stage, Capability) {
(Draft, Read);
(Published, Read);
};
};
postures {
policy { repetition(refused); };
};
projections {
companions;
relation_tables { policy; };
typestate(Stage);
};
}
}
}The relation remains a structural account: Macroonz knows that each endpoint belongs to its declared roster and that repetition is refused, but it does not know what a stage, capability, or allowed policy means.
The preset relation table projects baked::policy::contains(&Stage, &Capability), so ordinary code can use that checked account without rebuilding its membership loop.
Payload-bearing relations require an exact caller-authored lookup signature because the payload type remains caller authority; Macroonz supplies only the row-accounted Some or None body.
A same-roster evolution graph, a labeled many-to-many matrix, and a codec-only record use this same recipe entrance without pretending to be transitions.
When a recipe names codecs, those declarations select the existing compiler codec owner and its canonical methods rather than a parallel recipe encoding system.
When the ergonomic transition spelling is used, it lowers into one typed generic relation and unlocks the transition-specific dispatch projector.
One bake request admits progressively more precision without changing semantic models:
- A conventional bake supplies documented mechanical choices.
- A configured bake replaces named mechanical seats.
- An exact bake supplies caller-authored Rust for those same seats.
- A caller-owned projector consumes the same informed account and constrained output protocol through the callable compiler or a caller-owned proc host.
Projection syntax follows one grammar across the catalog:
dispatch; // documented conventional mechanics
dispatch(apply); // one flat configured name
dispatch {
/// Applies one caller-declared transition or returns typed absence.
pub fn advance(
current: State,
event: Event,
) -> Result<State, TransitionRefusal>;
}; // exact caller-authored Rust; Macroonz supplies only the checked bodyParentheses carry flat configuration names; braced seats carry the role's explicit bindings or exact Rust material.
An exact dispatch signature remains caller-authored Rust, including additional parameters when dispatch(state_binding, event_binding) { exact signature }; selects the two bindings consumed by the generated match.
The compiler's projection disclosure contract owns the exact-signature rules.
The standard projector owns the complete row-accounted match; individual rows may carry exact behavior through with(target) { exact Rust }, while a custom whole-function body belongs on the custom-projector road.
Two values for one seat refuse. Semantic postures are stated once in the structural account and consumed by every projector that needs them. Safe presets emit safe Rust, while an exact caller-authored unsafe boundary may be preserved or repeated only as explicit caller authority.
The callable compiler module remains the raw road for defining a new kind, grammar, or projection algorithm.
Its Kind and Request vocabulary exposes the same plan, render, closure, explanation, and expansion owners beneath the paved recipe surface rather than a second compiler model.
Every request walks the same eight steps, whatever the kind. Each step hands the next a value it cannot forge.
flowchart LR
accTitle: Compiler request road
accDescr: Every request proceeds from account through intent, context, plan, render, close, explain, and bind in that order.
A["1 · account"] --> I["2 · intent"] --> X["3 · context"] --> P["4 · plan"]
P --> R["5 · render"] --> CL["6 · close"] --> E["7 · explain"] --> B["8 · bind"]
- Account. The kind-specific content bound to its exact captured declaration and owner-qualified kind, plus every independent captured dependency it declares.
- Intent. What it means: an identity over the owner-qualified kind and content commitment. Two callers who meant the same thing derive the same intent.
- Context. Which profile and which generator version are answering.
- Plan. The complete output set, named before a byte of syntax exists — each unit's role, semantic key, destination, origin, expected profile, and digest contract — plus the invalidation set, the decision trace, and the nonclaims.
- Render. Typed tokens into rendered units, each digested over its own canonical bytes.
- Close. The membership is rebuilt from what was rendered and proved equal to the plan, role by role. The units are partitioned by the destination each one declared.
- Explain. Every question the kind owes is answered once, over that plan and that closure, under an identity derived from both.
- Bind. Plan, closure, and explanation are sealed together, after the compiler establishes that the three name one another.
The sealed expansion is the one value emission is read from.
emit() hands a proc macro its tokens; a test carrier, a bench carrier, or a publication step reads its own partition from the same value.
A request that cannot walk the whole road is refused whole. There is no partial output. A refusal is never a smaller success.
Expansion is a function of its declared input. No network, no filesystem scan, no environment, no clock, no entropy — there is no seat where one could enter.
You describe a subject once: what it takes, what it returns, what it refuses, what must hold. The harness hands you the instruments — each independently callable, composed by your own tests rather than by one button:
- Generates inputs against the description, structure-aware, from a seed it records.
- Injects faults on a declared schedule, and measures against a clock the caller declares, so the subject is judged under pressure and not on a sunny day.
- Reduces a failure to the smallest witness reached under the declared reducers and budget, and mints a replay capsule over it.
- Observes stable-Rust targets compiled with rustc coverage instrumentation through the pinned toolchain's matching LLVM tools, retains coverage-novel bytes, and hands them into that same reduction and replay road.
- Mutates the subject's own code and runs the trials against each mutant, to prove the trials can tell right from wrong.
- Benchmarks with the same receiver and the same pinned profile, so a number means the same thing tomorrow.
- Reports each verdict with its standing, its site, and its complete denominator — joined to its replay capsule, where a reduction earned one, on one execution key.
Descriptors, trials, mutations, and benches live in your tests — written through the generic macroonz::macros attributes, through your own attributes, or by hand.
The harness owns how they are judged, never what they mean.
The stable coverage path remains one-package usage through macroonz::harness::fuzz; its fuzz home owns the runnable facade example and command.
- Pick a posture from The three postures.
- Add
macroonzwith that command. - Start with
macroonz::recipe!, or follow the compiler README when you need a caller-owned projection algorithm. - Use the harness directly or through an evidence bake when an independent judgment is part of the recipe.
Runnable examples cross distinct public roads:
| Journey | Command | What it establishes |
|---|---|---|
| First recipe | cargo run --example recipe --no-default-features |
Generated lookups, codecs and dispatch execute independent expected values and absent-case controls. |
| Structural posture choices | cargo run --example recipe_postures --no-default-features |
Every relation posture admits lawful rows and refuses contradictions through the callable facade. |
| Declared codecs | cargo run --example codec_workflow --no-default-features |
Member shapes, direction choices and checked assembly agree with independent bytes and refuse malformed input. |
| Declared network and command orders | cargo run --example schedule_workflow --no-default-features --features harness |
Network faults and concurrency execute exact deliveries, expose and replay a caller-owned counterexample, and preserve sampled and exhaustive evidence. |
| Ordinary and shadow synchronization | Build and run the same adopter under both configurations | Generated imports connect caller-owned increments to ordinary execution and bounded Loom exploration, exposing a lost update and checking a separate repair. |
| Consuming transitions | cargo run --example consuming_workflow --no-default-features |
Owned resources and checked restoration through caller-declared runtime validation and effects. |
| Reusable admitted types | cargo run --example admitted_types --no-default-features |
Reusable patterns render nominal wrappers with caller-owned admission, bounds, visibility and encoding choices. |
| Declared typed trials | cargo run --example trial_workflow --features harness |
Co-located bindings and typed input execute through table-derived selection and versioned mechanical defaults, displaying complete results and an independent disagreement in JSON, Markdown and HTML. |
| Job declarations and independent checks | cargo run --example job_workflow --no-default-features --features harness |
Structural methods and unit-input trials share one recipe while caller-authored checks and text suite selection retain the complete denominator. |
| Retained input and fresh replay | cargo run --example retained_workflow --features native-tooling with explicit stdin actions |
An independent failure reduces to a reached witness, crosses bounded storage, and is replayed against separately selected current code. |
| Job work-count replay | cargo run --example job_retained --no-default-features --features native-tooling with explicit stdin actions |
The Job count law reduces to a retained witness and executes it in a fresh process without reduction, preserving a separate lawful control. |
| Callable compiler | cargo run -p macroonz-compiler --example callable_compiler |
One public compiler request plans, renders, closes, explains, binds, and emits a unit. |
| Direct handwritten property | cargo run -p macroonz-harness --example temporal_property |
Caller-owned state and transitions enter a temporal contract without a macro or subject trait. |
| Exact compile contract | cargo run --example compile_contract |
A caller-stated compiler observation is compared with an independently declared exact outcome. |
| Real compiler and read-back | cargo run --example compiler_workflow --features native-tooling with explicit stdin configuration |
A selected rustc builds a binary whose actual read-back is compared with an independent expected count. |
| Job compiler fixtures | cargo run --example job_compiler --no-default-features --features native-tooling with explicit Cargo configuration |
The Job declaration crosses a caller crate boundary, executes an independent lawful assertion and refuses a wrong state at an exact diagnostic anchor. |
| Job reader coverage | cargo run --example job_coverage --no-default-features --features native-tooling with explicit Cargo configuration |
The record reader retains independently expected novel inputs, refuses exhausted budgets and attributes every reported point to the selected fixture. |
| Stable coverage composition | cargo run --example rustc_coverage |
Stable rustc instrumentation supplies source-region novelty to corpus, reduction, and replay composition. |
| Bounded native coverage | cargo run --example coverage_workflow --features native-tooling with explicit stdin configuration |
Instrumented compilation, matching LLVM execution and corpus replay use bounded native processes. |
| Retained native mutation | cargo run --example mutation_workflow --features native-tooling with explicit stdin configuration |
A selected backend executes, retains its original command/source manifest and compares historical source claims with current files. |
| Independent mutation assessment | cargo run --example mutation_assessment --features native-tooling with explicit stdin actions |
Actual unchanged and mutated programs supply observations for independent weak and strong witnesses, followed by an unadmitted proposal, bounded historical retention and current-binding replay of the saved result. |
| Generated structural mutations | Generate a selected source, then execute compiler_workflow | Codec, transition and effect alternatives compile and disagree with unchanged, independently authored checks. |
| Declared enum mutation | Run the library-and-consumer example | Attribute and recipe carriers preserve generated order alternatives and withhold an unpermitted discovered point. |
| Generated publication | cargo run --example publication_workflow --features native-tooling with explicit stdin configuration |
One registered generator prepares, optionally formats, privately compiles, installs and checks its complete owned output. |
| Shared definition publication | cargo run --example job_publication --no-default-features --features native-tooling with explicit stdin configuration |
A shared macro and its sites retain complete destination checks while independent compiled assertions expose changed values. |
| Retained benchmark | cargo run --example benchmark_workflow --features native-tooling |
Real counted work and an executed worse control enter a complete benchmark report and bounded historical storage. |
The compile-contract example is intentionally the pure comparison half. The optional native compiler host executes explicitly configured rustc or Cargo fixtures, extracts structured diagnostics and connects compiled read-back to those same comparators.
For a specific task, start at its owner:
| Task | Start here |
|---|---|
| Write a recipe clause or configure a projection | Recipe clause forms |
| Generate consuming phase methods over caller-owned resources | Consuming transitions |
| Reuse checked newtype construction or typed fixture registration | Source patterns |
| Replace a projection algorithm | Callable projector |
| Define a kind, role or complete disposition set | Kind |
| Publish a shared macro definition and its adoption sites | Runnable publication |
| Compose generated tokens or preserve exact authored Rust | Token generation |
| Generate canonical encode and decode methods | Codec |
| Declare trial, benchmark or mutation material | Descriptor adapter |
Invoke deferred test or benchmark cargo through macroonz::support! |
Support carrier |
| Add an independent judgment | Handwritten property or Oracle |
| Replay a retained witness against current code | Saved-witness execution and Historical comparison |
| Execute declared input, retain a complete run and replay saved witnesses | Root workflow |
| Inspect or override versioned resource defaults | Mechanical configuration |
| Display complete results and owner-specific failures as JSON, Markdown or HTML | Presentation and Executable trial display |
| Run a benchmark and retain every reached outcome | Benchmark workflow |
| Execute compiler fixtures and compare exact diagnostics or compiled values | Native compiler fixtures |
| Execute coverage campaigns with bounded native tools and declared source roots | Native coverage |
| Execute mutations and retain source/version/command custody | Native mutation |
| Generate, format, check or recover owned published files | Publication commands |
| Interpret a refusal and its location | Diagnostic |
The shipped Macroonz agent skill is a one-page routing surface for agents authoring recipes from the packaged facade.
Contribution procedure lives in CONTRIBUTING.md.
Security reporting lives in SECURITY.md.
Cargo features are additive, so the lighter postures are selected by turning off the default before adding back only the door wanted.
| Posture | Command | Surface |
|---|---|---|
| full | cargo add macroonz |
Recipe entrance, compiler, proc declarations, harness, and the target-qualified preemption backend as the default posture. |
| diet-lite | cargo add macroonz --no-default-features --features harness |
Recipe entrance, compiler, proc declarations, and harness without Loom. |
| diet | cargo add macroonz --no-default-features |
Recipe entrance, compiler, and proc declarations; harness-owned evidence bakes are typed unavailable. |
The preemption feature always implies harness.
The harness feature also supplies macroonz::support!, root input execution, composing the existing decoder and complete-table runner, and record presentation.
On a native target supported by the pinned Loom backend, enabling preemption installs that backend.
On every other target, including Wasm, the same harness result plane remains available and reports typed backend unavailability instead of trying to compile Loom.
The optional native-tooling feature adds the root native clock source, bounded native storage, native process execution, compiler fixtures, native coverage, native mutation and publication commands, and implies harness without enabling preemption.
It is independent of the default full posture.
Pass macroonz::native_clock::source() to an existing harness runner or benchmark when native measurement is wanted; the harness retains its existing clock and measurement contracts.
AGENTS.md is the working law for anyone — person, model, or agent — who edits this repository, and it owns what enforcement means here.
CONTRIBUTING.md owns the exact local wall rather than duplicating a second command surface here.
That wall exercises every feature together, including the target-qualified Loom-backed preemption exploration, and crosses the supported Wasm posture separately.
The pinned stable Rust 1.98 toolchain also installs llvm-tools-preview, whose matching llvm-profdata and llvm-cov binaries read profiles for the safe-Rust fuzz composition road.
Licensed under either of Apache License, Version 2.0 or MIT license, at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
