The feature was built and never tested. Three things were missing.
The two packages holding a ring of macros and a macro that never settles
were not dependencies of the test stanza, so both non-termination
refusals failed on "no package at ..." rather than on their own reason.
They fire, and now the suite sees them fire.
The positive half of the rule had no acceptance case at all -- only the
refusal that pins the bare name. pkg-macro.flan is asserted at three opt
levels and on the dev path, which is where six package macros and the
program's own coexist in one file.
And the dev loop was broken in exactly the way that matters most here.
Session held the imported macro set but *replaced* it on every
evaluation, and the one form C-c C-c sends carries no import -- so
(mac/twice 4) compiled on the build and came back "unknown function" on
the first reload. It unions now. test_session drives two evaluations,
because one proves nothing: the first could have re-supplied the set.
BUILT.md said the expander collects from the prelude and the file being
compiled. It collects from imported packages too, and the refusal's old
reasoning -- that this needed a second import resolver -- was wrong for a
reason worth keeping written down.
Cold build cost roughly doubles for a program importing a package that
declares macros: a macro module is built per round and the package's
rounds are its own. Warm is unchanged at ~70ms.
Load.program takes forms: it reads the import forms, resolves them with the
one resolver it always had, and parses the file with the packages' macros in
front of it. The refusal said this needed a second import resolver at the Form
level. It did not notice that the file being compiled is parsed before Load
runs too, so no shape of the feature could have left import resolution where
it was.
Names arrive qualified, as a defn's do. (mac/twice 4) is a call and (twice 4)
is an unknown name.
Stopped mid-task: dune test was never run and the acceptance wiring is
unfinished. HANDOFF-macros.md has what is left.
handles.flan joins the ASan and memcheck corpora; pool-stale-region.flan
joins memcheck as a seventh program that aborts by design, for the reason
the other six are kept — a trap that stopped firing would be silent. Clean
both ways.