Skip to main content

MEP-55 implementation tracking

Per-phase tracking for MEP-55 Mochi-to-PHP transpiler. Status values: NOT STARTED, IN PROGRESS, BLOCKED, LANDED, DEFERRED. Commit is the merge commit short SHA on main.

A phase is LANDED only when its gate is green on every target listed for it in MEP-55 §Phases. Missing targets become N.1, N.2, ... sub-phases per the umbrella-phase coverage rule.

All 18 phases shipped together on impl/mep-0055-php, merged to main via PR #22481 on 2026-05-29 at 07:35 UTC (merge commit 7c72ebaae9).

Phase status

PhaseTitleStatusCommit
0Skeleton, scaffold, matrix CILANDED7c72ebaae9
1Hello world (print int/float/bool/string + newline shape)LANDED7c72ebaae9
2Scalars (int, float, bool, string, compare, arith, casts, control)LANDED7c72ebaae9
3Collections (lists, maps, sets, list-of-records)LANDED7c72ebaae9
4Records (final readonly class with constructor promotion)LANDED7c72ebaae9
5Sum types (abstract readonly base + final readonly variants)LANDED7c72ebaae9
6Closures and higher-order functionsLANDED7c72ebaae9
7Query DSLLANDED7c72ebaae9
8Datalog (compile-time semi-naive evaluation)LANDED7c72ebaae9
9Agents (userland Channel + final class)LANDED7c72ebaae9
10Streams (IteratorAggregate + subscribe_limit + drop branch)LANDED7c72ebaae9
11Async coloring (sync wrappers, no Amp/Revolt dependency)LANDED7c72ebaae9
12FFI (FFI extension + sodium dispatch)LANDED7c72ebaae9
13LLM (cassette dispatch with DJB2/GMP hash)LANDED7c72ebaae9
14fetch (curl, byte-equal against vm3)LANDED7c72ebaae9
15Composer runtime + PHPStan level 9 + Psalm 6 level 1 + php-cs-fixerLANDED7c72ebaae9
16Reproducibility (byte-equal by construction)LANDED7c72ebaae9
17Packaging (Phar + FrankenPHP + RoadRunner)LANDED7c72ebaae9
18Signed releases (GPG tag + Sigstore attestation + optional php-signify)LANDED7c72ebaae9

Audit follow-up PRs

Fourteen post-merge audit PRs (rounds 1 through 6) caught soft spots that the umbrella PR's CI did not. Each landed as its own PR on main:

RoundPRIssueFix
1#22568n/aStrengthen test assertions across phases 4/7/8/13 (DJB2 reimpl, fixture filename pinning)
1#22571n/aPhase 10.2 stream_backpressure fixture exercising subscribe_limit + drop branch
1#22575n/aPhase 9.1 spawn AgentType() lowering + agent_spawn fixture
1#22577n/aDrop unused amphp/revolt deps from runtime composer.json (Phase 11 is sync wrappers)
1#22579n/aColour pass docs honesty (no Phase 11 replacement; map stays all-Blue)
2#22594n/a-Inf branch fixture, empty-needle str_contains, empty-list sort, drop dead strCat flag
3#22596n/aLock Phase 1 emit shapes for int/float/bool/newline
3#22601n/aLock Phase 13 stderr-diagnostic branches (env-unset + cassette-missing)
3#22603n/aPin Phase 17 packaging config defaults (rr.yaml workers/timeouts, Caddyfile worker count)
4#22606n/aPin Phase 2 float-compare strict-equality shape (compare_float fragment row)
5#22616n/aHonest Driver.Deterministic doc (flag is a no-op; pipeline is deterministic by construction)
6#22625#22624Phase 13 non-empty model: field cassette-key fixture
6#22627#22626Phase 18 publish trust-chain: gate publish steps on GPG; audit-against-tarball; pin signify
6#22629#22628Honest fallthrough error messages in PHP lower.go (drop misattributed phase labels)

Known residuals

  • Mochi\\Runtime\\IO is dead from the lowerer's POV; emitted programs inline mochi_print_* helpers. The runtime IO class is kept as a downstream public-API surface and is annotated @api for Psalm's findUnusedCode rule.
  • php-runtime (8.5) matrix entry is allow_failure: true. A pass there does NOT mean Psalm + PHPStan passed; check step logs.
  • Live LLM providers (OpenAI, Anthropic, Google, llama.cpp) are deferred. Phase 13 ships cassette-only dispatch.