Source: https://github.com/coke/raku-ast-blin-results at 5b64b48.
Blin ran with RakuAST as the default frontend (rakudo 19a125e7e9 "Change default
to AST"; two modules bisected one commit earlier to 86dc6eac "test moarvm fix",
which is the same flip). Every failure in this run is therefore RakuAST-attributable.
Two things this run does not show.
- It was run with the proposed MoarVM serialization fix applied, so the whole "Object does not exist in serialization context" bucket (29 modules in the 2026-07-21 triage) is absent. That fix has not been turned into a PR.
- It predates rakudo
mainas of 2026-08-20 by a week, and its ecosystem snapshot is older still. 34 of the 53 were reinstalled and retested against a rakudo built frommaintoday; the results are in Re-verification below. Three rows are already resolved: SQL::Abstract and Data::Generators pass onmain, and Net::IP::Parse was fixed and released as 0.0.7 after blin's snapshot was taken.
Counts. 1422 OK, 53 fails, 2 flappers (Net::DNS, Selkie::UI — load-dependent,
not triaged here), 1 bogus ecosystem entry (Foo:: Foo), 400 AlwaysFail and 554
Unknown (fail on both frontends or never ran; out of scope).
Verdict
- RAKUDO — genuine RakuAST bug. Fix belongs in rakudo.
- MODULE — RakuAST is correctly stricter, or the module reaches into compiler internals it was never promised. Fix belongs in the module.
- MODULE (fragile) — the module's test asserts an implementation detail
(a backtrace index, a coverage line list, a mixin's exact
.WHAT). Both frontends are defensible; the test expectation has to become frontend-agnostic. - DEP — fails only because a dependency in another row fails.
- DEFERRED — known, decided not to chase.
PR status
- PR delivered — a pull request exists upstream (linked).
- fix ready, not delivered — a finished commit sits on a local branch in this workspace and was deliberately not sent upstream.
- rakudo PR open/merged — the rakudo-side change that clears it.
- none — nothing written yet.
| Module | Repo | Group | Verdict | Status |
|---|---|---|---|---|
| App::APOTD | deoac/apotd | G4 call analysis | MODULE | none |
| Array::Circular | lizmat/Array-Circular | G8 containers | RAKUDO | none |
| BioInfo | MattOates/BioInfo | G2 slang | RAKUDO | none |
| BioPerl6 | cjfields/bioperl6 | G6 RakuDoc | MODULE | none |
| CSS::Module | css-raku/CSS-Module-raku | G11 versions | DEP | none |
| CSS::Specification | css-raku/CSS-Specification-raku | G11 versions | MODULE | PR delivered (#6, merged, unreleased) |
| Code::Coverage | lizmat/Code-Coverage | G10 attribution | MODULE (fragile) | none |
| Control::Bail | skids/perl6-Control-Bail | G3 type strictness | MODULE | none |
| Data::Generators | antononcube/Raku-Data-Generators | — | flake | passes on main today |
| Dawa | ~bduggan/raku-dawa | G1 $*W |
MODULE | none |
| Env | lizmat/Env | G1 $*W |
MODULE | none |
| FindBin | lembark/raku-findbin | G3 type strictness | MODULE | none |
| FindBin::libs | lembark/raku-findbin-libs | G3 type strictness | MODULE | none |
| French | raku-multilingual/raku-french | G2 slang | MODULE | none |
| GD::Raw | raku-community-modules/GD-Raw | G6 RakuDoc | MODULE | PR delivered (#8, open) |
| Grammar::BNF | raku-community-modules/Grammar-BNF | G2 slang | MODULE | none |
| IRC::Log::Colabti | lizmat/IRC-Log-Colabti | G3 type strictness | MODULE | none |
| IRC::Log::Textual | lizmat/IRC-Log-Textual | G3 type strictness | MODULE | none |
| Image::Resize | raku-community-modules/Image-Resize | G6 RakuDoc | DEP (GD::Raw) | none |
| Inline::Perl5 | niner/Inline-Perl5 | G1 $*W |
MODULE | fix ready, not delivered |
| JSON::Fast | timo/json_fast | G3 binding strictness | MODULE | none |
| JobQueue | m-doughty/JobQueue | G12 unclassified | unknown | none |
| LIVR | koorchik/perl6-livr | G5 P5 regex | MODULE | none |
| List::Allmax | thundergnat/List-Allmax | G3 type strictness | MODULE | none |
| MergeOrderedSeqs | FCO/MergeOrderedSeqs | G3 type strictness | MODULE | PR delivered (#1, merged, unreleased) |
| Net::IP::Parse | bradclawsie/Net-IP-Parse | G3 type strictness | MODULE | PR delivered (#8, merged and released in 0.0.7) |
| OpenMPT::Bindings | sasha/OpenMPT-Bindings | G8 NativeCall at CHECK | RAKUDO | none |
| P5__DATA__ | lizmat/P5__DATA__ | G2 slang | MODULE | none |
| P5tie | lizmat/P5tie | G7 dynamic-scope pragma | MODULE | none |
| Pod::Perl5 | dnmfarrell/Pod-Perl5 | G9 regex/Match | unknown | none |
| Polyglot::Regexen | alabamenhu/PolyglotRegexen | G1 $*W |
MODULE | none |
| Portuguese | raku-multilingual/raku-portuguese | G2 slang | MODULE | none |
| Proc::Easier | sdondley/Proc-Easier | G10 attribution | MODULE (fragile) | none |
| Regex::FuzzyToken | alabamenhu/RegexFuzzyToken | G9 regex/Match | RAKUDO | none |
| RegexUtils | grizzlysmit/RegexUtils | G5 P5 regex | MODULE | none |
| Router::Right | pheix/raku-router-right | G5 P5 regex | MODULE | none |
| SION | dankogai/raku-sion | G9 regex/Match | RAKUDO | none |
| SQL::Abstract | Leont/sql-abstract | G4 call analysis | — | fixed since the run |
| SQL::Lexer | dmaestro/SQL-Lexer | G9 parse strictness | MODULE | none |
| ScaleVec | samgwise/p6-ScaleVec | G12 unclassified | unknown | none |
| SelectiveImporting | wukgdu/raku-SelectiveImporting | G2 slang | MODULE | none |
| Selkie | m-doughty/Selkie | G6 RakuDoc | MODULE | none — retest 0.15.1 first |
| Slang::Forgiven | mustafaaydn/Slang-Forgiven | G2 slang | MODULE | none |
| Slang::Mosdef | bduggan/mosdef | G2 slang | MODULE | none |
| Slang::Predicate | samgwise/p6-Slang-Predicate | G2 slang | MODULE | none |
| Sustenance | repo unavailable (github:atweiden) |
G12 unclassified | unknown | none |
| T | CIAvash/T | G2 slang | MODULE | none |
| Test::Stream | raku-community-modules/Test-Stream | G10 attribution | MODULE (fragile) | PR delivered (#5, open) |
| Tie::Array | lizmat/Tie-Array | G7 dynamic-scope pragma | DEP (P5tie) | none |
| Tie::StdArray | lizmat/Tie-StdArray | G7 dynamic-scope pragma | DEP (P5tie) | none |
| Web::Cache | scmorrison/perl6-Web-Cache | G10 attribution | MODULE (fragile) | none |
| XHTML::Writer | gfldex/perl6-xhtml-writer | G3 type strictness | MODULE | none |
| auto-dynamic | lizmat/auto-dynamic | G1 $*W |
DEFERRED | none |
RakuAST has no $*W. Reading it throws Dynamic variable $*W not found, usually
from a sub EXPORT running at BEGIN time.
- Dawa, Env, Polyglot::Regexen — direct
$*Winsub EXPORT. - Inline::Perl5 — same, plus the
v5slang, which is a separate porting gap. 35 of 42 test files pass with the$*Whalf worked around; theuse v5slang half needs its own port. Arakuastbranch inscratch/Inline-Perl5carries the$*Whalf and was never delivered. - auto-dynamic — DEFERRED by earlier decision. Its exported
&DYNAMIChooks an implementation-detail sub; a one-line fix is known but the module is asking for something the frontend does not promise.
What has to change. Port each $*W use to $*R (the RakuAST resolver) plus the
$*CU/$*LANG surface. Four modules in this family have already been ported and
merged this way and no longer appear in the run — CompUnit::Util
(PR #1),
Benchy (PR #3),
overload::constant (PR #1),
and FINALIZER (PR #4). Those are the
templates to copy.
Modules that mix a role into the MAIN grammar, augment Raku::Grammar, add
package_declarator rules, or hook World.do_import.
- French, Portuguese — declare custom infix operators; RakuAST reports
Lexical symbol '&infix:<...>' is already bound to an outer symbol. - Slang::Forgiven, Slang::Mosdef — new statement/term syntax; RakuAST reports
Unexpected block in infix position. - Slang::Predicate — custom operators; output carries a stray
α\tprefix. - T — mixes a
T::Grammarrole into$*LANG.slang_grammar('MAIN')to add atterm. Under RakuAST the term never registers, soraku -M T -e 't 2 == 2'reportsUndeclared routine: t. - P5__DATA__ — augments the grammar;
Method Raku::Grammar+{Data}.pod_newline not found. - SelectiveImporting — uses the World
do_importhook for:select/:exceptimport tags; RakuAST reportsno such tag 'select'. - Grammar::BNF — the serialization half was fixed; two slang test files remain.
- BioInfo — the odd one out and the only RAKUDO verdict in this group:
Cannot find method 'to-begin-time' on object of type QAST::Op. A slang path hands RakuAST a raw QAST node where it expects an AST node.
What has to change. For everything but BioInfo this is a language-surface
question, not a bug: RakuAST needs a supported slang story, or each module needs
rewriting against $*LANG.slangs and the RakuAST grammar's own extension points.
Test::Async was ported this way successfully
(PR #3, merged), so custom
declarators are portable; custom operators and terms are the harder half.
BioInfo needs a rakudo-side fix at whichever slang entry point accepts a QAST::Op.
Legacy skipped a nominal or return type check; RakuAST performs it and the module's own signature turns out not to describe what it is passed.
-
List::Allmax (
expected Callable[Callable] but got Block), MergeOrderedSeqs (expected Order but got Block), XHTML::Writer (expected Positional but got Str) — a*@slurpyahead of a typed parameter made legacy skip the typed parameter's nominal check. -
IRC::Log::Colabti, IRC::Log::Textual —
expected Positional[Str] but got Array (["tyil"]). The value has to be an explicitly typed array. -
Net::IP::Parse —
Type check failed for return value; expected Positional[...UInt8]:D. Fix is to build and return a typed array. -
Control::Bail —
This type (Failure) does not support associative operations. -
FindBin, FindBin::libs —
This type cannot unbox to a native string: P6opaque, Junction. A Junction reaches a native-string slot. -
JSON::Fast —
Parameter '$pos' expects a writable container (variable) as an argument, but got '5' (Int) as a value without a container. The module passes++$posto anotherint $pos is rwparameter.prefix:<++>yields a value, not a container, so this is not supposed to bind — and both frontends agree in three of the four shapes:shape legacy RakuAST Int $n is rw,++on a lexicalrejects rejects int $n is rw,++on a lexicalrejects rejects Int $n is rw,++on a forwardedis rwparamrejects rejects int $n is rw,++on a forwardedis rwparamaccepts rejects Legacy accepting the fourth row is the outlier, inconsistent with its own answer in the other three. RakuAST is the consistent one. Module fix: use the
$pos = nqp::add_i($pos, 1)form the same file already uses elsewhere.
What has to change. Module side, one signature or one construction each. Do not
relax rakudo for these. Two are already done: MergeOrderedSeqs
(PR #1) is merged but unreleased, so
blin still installs the broken 0.0.1; Net::IP::Parse
(PR #8) is merged and
released — 0.0.7 passes on main today, and blin only failed because its snapshot
still tested 0.0.6.
-
App::APOTD —
Calling mail-die(Str, Str, Str, Str) will never work with declared signature (Str $msg). The module really does pass four arguments to a one-argument sub. Legacy skipped the check because one of the arguments is an interpolated string; RakuAST checks it anyway. Minimal difference:sub main() { my $r = 1; mail-die "a", "b {$r}", "c", "d"; # legacy: silent. RakuAST: SORRY sub mail-die (Str $msg) { die $msg } }
Module fix: concatenate the four pieces into one string.
-
SQL::Abstract —
Calling split-source(SQL::Abstract::Source:D) will never work with any of these multi signatures. No longer reproduces: the released 0.0.9 tarball compiles and tests clean on rakudomainas of 2026-08-20. Nothing to do.
- LIVR — a
rx:P5literal backs theurlrule, so the validator rejects valid URLs. - Router::Right —
s:Perl5:g/^\s+|\s+$//; strings keep their surrounding whitespace, so" DELETE "never matches and%h<controller>comes back undefined. - RegexUtils —
EVAL "rx:Perl5$flags/$rg/"inCreatePerlRegex.
What has to change. Module side: use Raku regexes. Note that the decision has
already been made to make :P5 a hard compile-time error
(rakudo PR #6534, open), so these three
will change from wrong answers to a clean X::Syntax::Regex::P5 once it lands. That
is an improvement, not a regression, but it does mean these modules break loudly
rather than quietly.
RakuAST's RakuDoc parser rejects markup that the legacy parser silently repaired.
- GD::Raw — one
L<...>link is missing its closing>; the legacy parser consumed the next link's>to close it. Fix is one character, delivered as PR #8, still open. - Selkie —
RakuDoc markup code C missing endtag '>>'inlib/Selkie/App.rakumod. Blin tested 0.14.1; 0.15.1 has since been released and itsApp.rakumodno longer contains aC<<at all, so retest before touching this one. - BioPerl6 —
=begin endinlib/Bio/Role/Range.pm6;=beginmay not be followed by the directiveend. - Image::Resize — DEP: it fails only on
use GD::Raw.
What has to change. Fix the pod. Worth a decision on whether rakudo should be lenient here instead; the current behaviour is defensible and the modules are wrong, but four modules is a real cost for a documentation typo.
P5tie, and Tie::Array / Tie::StdArray which depend on it.
FETCH/STORE never fire, so tied variables read back as Any and pushes return the
wrong thing.
Legacy only worked because World.nqp hardcodes a P5-name-prefix hack that applies
the dynamic-scope pragma to importing files. With that hack removed, legacy fails
15 of 17 exactly like RakuAST — so this is module-side, not a RakuAST regression.
The fix is for P5tie to request the pragma itself from sub EXPORT via
$*LANG.set_pragma, before the unit declaration; that gets 17/17 on both frontends
with a workaround-free compiler. Nothing has been delivered upstream.
-
Array::Circular — a trait whose argument is a declaration is silently not applied:
use Array::Circular; my @b is circular(my $); # legacy: SORRY, requires a compile-time constant # RakuAST: trait never runs, @b is a plain Array
Silently dropping a trait is worse than the error the module wants to raise.
-
OpenMPT::Bindings — a NativeCall sub cannot be called from a
CHECKphaser:use NativeCall; sub getpid() returns int32 is native { * } CHECK { say "CHECK: ", (try getpid()) // "FAILED: $!" } say "RUN: ", getpid(); # legacy CHECK: 53854 RUN: 53854 # RakuAST CHECK: FAILED: lang-call cannot invoke object of type 'VMNull' ... RUN: 53857
The module probes
openmpt_get_library_version()from aCHECKblock to fail early with a friendly message, so under RakuAST every consumer sees the VMNull text instead. The same shape also masks a genuinely missing library: with the.dylibabsent, legacy reportsCannot locate native libraryand RakuAST reports the VMNull invoke, which is how this looked in the blin log.
-
SION — RAKUDO, and the widest-reaching find in this run.
m:p($pos)ignores its argument:my $b = 'abc123'; say ($b ~~ m:p(2)/\w+/).?from; # legacy 2, RakuAST Nil say ($b ~~ m:p(4)/\w+/).?from; # legacy 4, RakuAST 0 say ($b ~~ m:p(1)/\w+/).?from; # legacy 1, RakuAST Nil
RakuAST appears to fall back to the string's stored continuation position, which is why results alternate as each match leaves a new
.tobehind. Any hand-written parser that walks a string withm:p($pos)is affected; SION is just the one that showed up here. -
Regex::FuzzyToken — RAKUDO. Importing the same
sub EXPORTmodule twice in one compilation unit breaks the second import's wrap:grammar A { use Regex::FuzzyToken; token TOP { $<a> = <fuzzy: <aaa bbb ccc>, /<.alpha>+/> <.digit>+ } } grammar B { use Regex::FuzzyToken; token TOP { $<b> = <fuzzy: <111 222 333>, /<.digit>+/> <.alpha>+ } } say A.parse("aab323892")<a>.Str; # legacy "aaa", RakuAST Any
With only grammar A present both frontends agree. Adding the second
usebreaks both. The module's&fuzzy.wrap(...)mixes a role into the match using two dynamic variables set inside a<?{ }>assertion; under RakuAST that communication is lost once the module is imported twice. -
Pod::Perl5 —
$match.capsyields entries whose.value.madeisAny, so the HTML and Markdown serializers emit empty strings. Not root-caused; same neighbourhood as the two above. -
SQL::Lexer — MODULE.
grammar Basic:ver<0.2.2> is Lexer:ver<0.2.1..*>— legacy ignored a:veradverb inisposition, RakuAST reads it and reportsInvalid type smiley ':ver'. The module has to drop the adverb from theisclause.
None of these are wrong answers; they are tests asserting a compiler-internal shape.
-
Proc::Easier — walks
Backtrace.new.listwith hardcoded+1/+2offsets after filteringSETTINGframes. RakuAST's frame layout differs by one, so it reports the module's own file and a line one short. -
Test::Stream — expects a specific reported line (186) and gets another (76). Already addressed by PR #5 (open), which makes the expectations frontend-agnostic.
-
Code::Coverage — the coverage line list drops line 9. Line 9 sits in an
ifbranch that never executes on that run, so RakuAST's answer is arguably the correct one; legacy emitted a coverage annotation for it anyway. Real consequence: coverage numbers shift for everyone, so this is worth a conscious decision rather than only a test edit. -
Web::Cache —
expected: (Block)/got: (Block+{Callable[Str]}). RakuAST attaches theCallable[T]mixin to a pointy block with a return constraint; legacy attached it tosubbut not to->. RakuAST is the consistent one:my $c = -> --> Str { "y" }; say $c.WHAT; # legacy (Block), RakuAST (Block+{Callable[Str]}) my $b = sub (--> Str) { "z" }; say $b.WHAT; # both (Sub+{Callable[Str]})
- CSS::Specification —
Could not find CSS::Grammar:ver<0.3.0..*>. Legacy ignored:ver, RakuAST honours it, and a Range is not a valid:verargument. Fixed upstream by PR #6 (merged), which has not been released, so blin still installs 0.5.3 and still fails. - CSS::Module — DEP: its only failing assertion is the CSS::Specification version check.
Worth a look but nothing verified beyond the observable.
- JobQueue —
JobQueue::EventSink.new.dispatch('x')should die with "must be implemented" and instead dies with "Stub code executed". Reduced versions of the role, theunit roleform, precompilation, and composing-then-punning all behave identically on both frontends, so something about the installed dist is doing it. - ScaleVec —
Cannot pop from an empty Array[ScaleVec::Chord::Graph::PV]in the progression planner. - Sustenance —
Use of uninitialized value of type Rat in numeric contextinside a WhateverCode. The upstream repo appears to be gone, so this may be unfixable module-side.
34 of the 53 were reinstalled and retested with zef against a rakudo built from
main today (ac2ce1c1ce, which is origin/main plus two unrelated local commits),
with RAKUDO_RAKUAST=1. This is what changed in the week since the blin run.
| Module | Still fails | Note |
|---|---|---|
| Array::Circular | yes | |
| Code::Coverage | yes | |
| Env | yes | |
| French | yes | |
| GD::Raw | yes | |
| Grammar::BNF | yes | |
| IRC::Log::Colabti | yes | |
| IRC::Log::Textual | yes | |
| JSON::Fast | yes | |
| JobQueue | yes | |
| List::Allmax | yes | |
| MergeOrderedSeqs | yes | |
| Net::IP::Parse | 0.0.6 yes, 0.0.7 no | the released fix postdates blin's snapshot |
| OpenMPT::Bindings | yes | root-caused today, see G8 |
| Polyglot::Regexen | yes | |
| Portuguese | yes | |
| Proc::Easier | yes | |
| RegexUtils | yes | |
| Router::Right | yes | |
| SION | yes | root-caused today, see G9 |
| Selkie | yes (0.14.1) | 0.15.1 released since; its App.rakumod no longer has the bad markup |
| SelectiveImporting | yes | |
| Slang::Forgiven | yes | |
| Slang::Mosdef | yes | |
| T | yes | |
| Test::Stream | yes | PR #5 not merged yet |
| Tie::Array | yes | |
| Tie::StdArray | yes | |
| auto-dynamic | yes | |
| App::APOTD | yes | |
| Data::Generators | no | 0 failing test files; the 0.4169-vs-0.4 assertion was a flake |
| SQL::Abstract | no | released 0.0.9 compiles and tests clean |
| P5tie | not retested | already installed as a Tie::Array dependency, so zef skipped its tests |
| CSS::Specification | inconclusive | local run hit a dependency-resolution artifact, not the :ver failure |
The 19 not retested here are the ones whose cause was already settled by the 2026-07-21 triage or by inspection: BioInfo, BioPerl6, CSS::Module, Control::Bail, Dawa, FindBin, FindBin::libs, Image::Resize, Inline::Perl5, LIVR, P5__DATA__, Pod::Perl5, Regex::FuzzyToken (reproduced separately, see G9), SQL::Lexer, ScaleVec, Slang::Predicate, Sustenance, Web::Cache, XHTML::Writer.
- G9 SION's
m:p($pos)— a silently wrong regex match position is the worst kind of bug in this list, and nothing in the ecosystem can work around it. - G8 Array::Circular's silently dropped trait — small, self-contained, one-line repro, and silence is the worst possible failure mode for a trait.
- G9 Regex::FuzzyToken's double import — "importing a module twice breaks it" is a broad hazard that happens to have surfaced in one module.
- G8 NativeCall in a
CHECKphaser — one repro, and it degrades every module that probes its native library early. - G2 BioInfo — the only rakudo bug hiding in the slang group.
- Chase the module PRs that are already sitting upstream — GD::Raw #8 needs a review, MergeOrderedSeqs #1 needs a release, Test::Stream #5 needs a review, and CSS::Specification #6 needs a release. Four rows clear with no new code.
- G3 and G5 — straightforward module PRs, one signature or one regex each.
- G6 — decide leniency-or-fix once, then act on all four.
- G1 and G2 — the
$*Wand slang batch needs a policy decision before any more module PRs, since the port pattern is only settled for the$*Whalf.
- The MoarVM serialization fix this run was built with is still a local patch. It is the single largest lever in the ecosystem (29 modules in the 2026-07-21 run) and needs to become a PR.
Net::DNSandSelkie::UIcame back Flapper. Blin flappers on this box have historically been load-dependent rather than real.Foo:: Foois a malformed ecosystem entry, not a module.
The
P5tie,Tie::Array,Tie::Hash,Tie::StdArrayandTie::StdHashdistros have been reduced to modules that pass testing, but can no longer be installed.