StowLM

Research pilot · container stowage · Meta hackathon

StowLM

The AI pipeline around a ship-planning engine, as an app. Messy voyage documents and a planner's own words go in, a checked plan and a handover package come out, with a fine-tuned Meta model on the laptop reading every instruction.

Models propose. Software decides.

Launch cut. Synthetic ships and cargo, simulated port. Music: Sascha Ende, ende.app (CC BY 4.0)

A forward pilot, built to scale

A feeder ship's loading plan starts from paper: a tally sheet, an email that contradicts it, a limit called over a bad radio line. StowLM is the AI pipeline that turns that mess into a plan the full checker passes and a handover package for the ship's master, delivered as an app. Muse Spark reads the cargo papers, Muse Voice Transcribe hears the planner, a fine-tuned Muse Glimmer 30B reads the planner's own words into rules on the laptop, the planner confirms each reading, the engine plans the section, and a checker with 54 active rules decides. The engine sits in one slot: ours today, and by design a firm's own planning software. Today's pilot runs the loop on synthetic ships inside a stated design limit. It is a forward pilot, built to scale: more compute for the search, a larger model for reading.

How it fits together

Pipeline diagram. Voyage documents go to Muse Spark (cloud), which reads paper and finds where documents disagree; a planner's spoken words go to Muse Voice Transcribe (cloud). StowLM Reader, Muse Glimmer 30B with our LoRA adapter on the laptop, reads the words into rules under a feasibility decode mask: 118 of 128 on the locked reader test, against 60 of 128 untrained under the same mask; it cleared the 90 % gate and missed two stricter ones. The mask overrode the model's first choice on 182 of 200 validation sentences before fine-tuning and 2 after; almost all were output format, none an illegal bay or tier, and both of the 2 were sentences it should have refused. The planner confirms the reading, Frontier Engine 0.13.0 plans, the full checker decides with 54 active rules in tiers, and a signed handover package comes out. All of it is one hashed pipeline, manifest v4.
One hashed pipeline (manifest v4). Amber: Meta Model API, cloud. Green: on this laptop. Grey: software. Synthetic ships and cargo, simulated port.
Inside the reader as it writes. Before fine-tuning, the mask overrode the model's first choice in 182 of 200 validation sentences. After: 2. Almost all were the output format, not ship facts; none was an illegal bay or tier. Both of the 2 were sentences it should have refused; what's left is legal and still wrong, which is why a person confirms. Recorded answer; 200 validation sentences, not the locked test.

One slot for the engine

Design and potential: only Engine 0.13.0 is wired in; no third-party engine has been ported

Everything around the engine is the pipeline: the paper intake, the instruction readers, the planner's confirmation, the full checker, the rule-tier ladder, the signed handover and both apps. Frontier Engine 0.13.0, our search software, is the reference engine in the slot. The design lets a carrier, terminal or stowage-software vendor put its own planning software there and keep everything around it.

What the slot is today. The runner reaches the engine through one binding (execute_brief and plan_with_rules: the instance and the planner's confirmed rules in, a plan in the pipeline's own format out). The runner then checks that plan itself on the original instance, with the full checker and every confirmed instruction, before anything is drawn or packaged, and the binding pins the engine's source manifest. In the held-out evaluation the simple two-step planner's plans went through the same checker and tier classification, so the gate already judges two different planners; that ran in the evaluation harness, not through the app's slot.

What a port would take. The firm's software behind those two functions, its own source pin, and its own way to honour the confirmed rules (today the binding applies them inside Engine 0.13.0). Every result on this page was measured with Engine 0.13.0 in the slot and says nothing about another engine.

Code: experiments/mvp/pipeline/binding/adapter.py, called from experiments/mvp/pipeline/runner/core.py (engine_call); plan format src/stowage/model; evaluation gate experiments/mvp/pipeline/sealed/worker.py.

Three Meta models, each with one job

On the laptop · fine-tuned by us

Muse Glimmer 30B, as StowLM Reader

Fine-tuned with LoRA. Reads the planner's words into rules, on device. It reads free wording of four kinds of instruction and is built to refuse anything else; it can slip, so the planner confirms.

118 of 128 (92.19 %) on a locked reader test, against 60 of 128 (46.88 %) for the untrained Glimmer under the same mask: same model, same laptop, with and without our fine-tune.

Named comparison: Muse Spark read 126 of 128 (fixed reference, earlier mask, not rerun). The reader cleared the 90 % gate and missed two stricter ones: it accepted one loosening where none was allowed, and it sits 6 points below Spark where 3 were allowed.

New wording from another model (100 synthetic sentences, one pre-registered run, not real planner text): 86 of 100 read exactly, against 45 without our fine-tune; 61 of 66 rules, against 18. It also made a rule from 6 of 34 sentences it should have refused, so a person confirms every reading. It read 4 of 5 Thai-English sentences.

Meta Model API · cloud

Muse Spark

Reads paper and pictures, finds where documents disagree, and chooses tools in the copilot. Spark's raw text gets strict flags, and software holds back every flagged line.

Meta Model API · cloud

Muse Voice Transcribe

Turns speech into an editable transcript, so a limit called over the radio reaches the reader as text the planner can fix.

Plans come from Frontier Engine 0.13.0, our search software and the reference engine in the slot, not from a language model. The full checker decides: 54 active rules, with 8 catalogue entries off as run. Every plan shown has been through it, and a plan that doesn't pass says which rules it breaks.

Held-out test voyages

held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim

24 of 24

held-out maps inside the envelope, all full checker passes (exact 95 % interval 85.8–100 %). Held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim.

13 of 18

Of the 18 voyages whose first plan broke the rule, 13 got a checked plan that obeys it (46.5–90.3 % exact 95 % interval); on the other 6 the first plan already obeyed it, which proves nothing.

0 of 24

for a simple two-step planner, modelled from one field expert's description (interval 0–14.2 %; 10 relaxed, 14 no plan). It isn't a measure of how good planners work; experienced planners may already block by port.

Fresh held-out extension

fresh held-out extension, run after the freeze; not the pre-registered sealed claim

24 of 24

On 24 fresh held-out maps, the pipeline returned a full-checker pass on all 24 (exact 95 %: 85.8-100 %). Fresh held-out extension, run after the freeze; not the pre-registered sealed claim.

1 of 24

for the simple two-step planner (0.1-21.1 %).

18 of 22

With one instruction, 18 of 22 voyages whose first plan broke the rule got a checked plan that obeys it (59.7-94.8 %).

24 new envelope maps from new seeds, pre-registered (PREREG sha256 ba3dcc46…), run on manifest v4 (planning code byte-identical to v3). The first held-out run above stays the headline result; this extension is reported beside it.

Secondary figure, pooled: Pooled with the first held-out run (secondary figure): 48 of 48 envelope maps passed the full checker (92.6-100 %); binding 31 of 40 (61.5-89.2 %). The two runs are separate experiments, not one.

Source: experiments/mvp/pipeline/sealed/measurements/ext-1/FIGURES.json; independent recount experiments/review/v6/code15.md. Wording from docs/headline.md, "Fresh held-out extension (ext-1, D333)".

No lift saving is quotable. In the first held-out run the two-step baseline never passed the full checker, so there are no mutual passes and no like-for-like lift comparison. In the extension the two-step planner passed 1 of 24, a single mutual pass, too few for a lift comparison, so no lift figure is quoted there either.

Two earlier attempts on the same maps stopped early when our own frozen-code guard tripped. In the first, a test rewrote a pinned fixture; in the second, the engine wrote scratch files inside its pinned folder. No planning code changed. They completed 36 and 91 rows; both are published as they are and not pooled with the final run. Where the same rows ran again in the final run, attempt 1 matched the final run on 36 of the 38 rows it opened (status and lifts; 37 of 38 on verdict alone) and attempt 2 on 91 of 91, reported separately.

The envelope. Up to 195 boxes in a half-ship section of feeder ships of 500–800 TEU, up to 70 % of that section: an empty section on a ship whose other bays hold fixed synthetic cargo, one loading call. Outside it, the pipeline says so and gives the reason. The engine isn't competitive at large scale yet. The held-out number is the planning step from a clean load list. Confirmation in this run is exact expected-rule match, not a human planner. Navis and human-planner performance aren't public.

Source: experiments/mvp/pipeline/sealed/runs/final-3/story-figures.json (/cohorts/envelope24/arms/pipeline/passes_L0, /cohorts/envelope24/arms/pipeline/passes_L0_exact95, /cohorts/envelope24/arms/twostep/passes_L0_exact95, /instruction/binding_obedient_passes, /instruction/binding_obedient_exact95, /lift_claim/quotable); reader figures and wording from docs/headline.md.

The recorded results, charted

Recorded results only; no planning or model rerun. Synthetic ships and cargo, simulated port.

Chart: full-checker passes by cohort and ship size, held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim. Pipeline with no voyage instruction against a simple two-step planner, with exact two-sided 95 % intervals. Tiny, 500 to 800 TEU: pipeline 10 of 10 (69.2 to 100 %), two-step 0 of 10 (0 to 30.8 %). Tiny, 1,700 TEU, outside the envelope wording: 5 of 5 (47.8 to 100 %) against 0 of 5 (0 to 52.2 %). Small, 500 to 800 TEU: 20 of 20 (83.2 to 100 %) against 0 of 20 (0 to 16.8 %). Small, 1,700 TEU, outside the envelope wording: 9 of 10 (55.5 to 99.7 %) against 0 of 10 (0 to 30.8 %). Envelope, 500 TEU: 12 of 12 (73.5 to 100 %) against 0 of 12 (0 to 26.5 %). Envelope, 800 TEU: 12 of 12 (73.5 to 100 %) against 0 of 12 (0 to 26.5 %). Envelope total, same maps: 24 of 24 (85.8 to 100 %) against 0 of 24 (0 to 14.2 %). A pass means a full checker pass, completion and every confirmed instruction obeyed; relaxed plans aren't passes. No like-for-like lift comparison is available.
Full-checker passes by cohort and ship size. Held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim (two earlier runs stopped on our own guard, both published; see above). 1,700 TEU rows are outside the envelope wording, and tiny and small maps are never pooled with the envelope. Planning step from a clean load list.
Chart: envelope full-checker passes, the first held-out run beside the fresh extension. First run: held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim; pipeline 24 of 24 (85.8-100 %), simple two-step planner 0 of 24 (0-14.2 %). Fresh held-out extension, run after the freeze; not the pre-registered sealed claim: pipeline 24 of 24 (85.8-100 %), two-step 1 of 24 (0.1-21.1 %). Secondary pooled figure, labelled as such: 48 of 48 (92.6-100 %).
Envelope passes: first held-out run and fresh extension. First run: held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim. Extension: fresh held-out extension, run after the freeze; not the pre-registered sealed claim. The pooled 48 of 48 is a secondary figure, not one experiment.
Chart: instruction binding. First held-out run (held-out maps, frozen pipeline, run after two interrupted attempts; not the pre-registered sealed claim): of the 18 voyages whose first plan broke the rule, 13 got a checked plan that obeys it (46.5-90.3 %); on the other 6 the first plan already obeyed it. Fresh held-out extension, run after the freeze; not the pre-registered sealed claim: 18 of 22 (59.7-94.8 %); on 2 the first plan already obeyed it.
Instruction binding. First held-out run: of the 18 voyages whose first plan broke the rule, 13 got a checked plan that obeys it (46.5–90.3 % exact 95 % interval); on the other 6 the first plan already obeyed it, which proves nothing. Fresh held-out extension, run after the freeze; not the pre-registered sealed claim: 18 of 22 (59.7-94.8 %). By type the samples are small; quoted only with their denominators.
Chart: StowLM Reader exact match on its locked test of 128 sentences, locked before tuning and scored once. Adopted v3 reader 118 of 128 (92.19 %); untrained Glimmer under the same mask 60 of 128 (46.88 %); a no-model parser 90 of 128 (70.31 %); Muse Spark reference 126 of 128 (98.44 %), the fixed original reference, not rerun. Gates: passed the 90 % gate; missed both stricter ones, with 1 of 48 loosening sentences accepted where none was allowed, and 6.25 points below Spark where 3 were allowed. Adoption context: v3 118 of 128 with 1 of 48 loosenings accepted; v2 120 of 128 with 2 of 48.
Reader on its locked test. 118 of 128 against 60 of 128 untrained: same model, same laptop, with and without our fine-tune. Muse Spark read 126 of 128 (fixed reference, earlier mask, not rerun). It cleared the 90 % gate and missed two stricter ones. v2, shown beside it, read 120 of 128 but accepted 2 of 48 loosenings. This set isn't a held-out planning map.
Chart: decode-mask overrides before and after fine-tuning, on 200 validation sentences. Before fine-tuning, the mask overrode the model's first choice in 182 of 200 sentences. After: 2. Almost all were the output format, not ship facts; none was an illegal bay or tier. Both of the 2 were sentences it should have refused; what's left is legal and still wrong, which is why a person confirms. This measures intervention by the mask, not correctness of the reading; end-token swaps are excluded.
Decode-mask overrides. Before fine-tuning, the mask overrode the model's first choice in 182 of 200 validation sentences. After: 2. Almost all were the output format, not ship facts; none was an illegal bay or tier. Both of the 2 were sentences it should have refused; what's left is legal and still wrong, which is why a person confirms. Validation sentences, not the locked test.

Charts: experiments/mvp/charts/ (sources and SHA-256 hashes in its README.md); copied byte for byte.

Why it matters, if it scales

Who it's for: the planners who load feeder ships at ports like Laem Chabang, where a load plan starts from a tally sheet, an email and a radio call; and, through the engine slot, carriers, terminals and stowage-software vendors who could keep their own planning software and add the pipeline around it (potential; nothing ported yet). A forward pilot, built to scale: more compute for the search, a larger model for reading.

Projection, not a result. None of it has been measured.

Bad load plans cost about $0.35 to $6.6 billion a year worldwide, mid about $2.4 billion, across restow fees, fuel, lost slots, delay and safety, and 0.03 to 5.6 deaths a year (mid 0.7) (projection; docs/load-plan-losses.md). The figures below are the narrower part a better plan acts on directly.

about $90 billion a year

of port-call cost worldwide, so every 1 % is about $1 billion. Projection: exposure

about $2.3 billion a year

of extra crane work and berth time that a better plan can act on (mid case; low $0.3 billion). Projection: pool

$63–76 billion a year

Check: world terminal revenue, analyst estimates. The mid-case restow line ($0.42 billion) sits inside it, not on top of it.

About $40 million a year at Laem Chabang if scaled by its share of calls (projection; 9,325 of about 520,000 calls, 1.8 %). Half the pool is lifts, which scale with TEU, and the port's calls skew to feeders, so this is a share of calls, not a port estimate.

Inputs

  • 920M TEU handled a year (UNCTAD, 2024)
  • 520k container-ship calls a year (UNCTAD, rounded)
  • assumed 0.9 % avoidable restows, at $75 a lift
  • assumed 5 % less berth time if the extra work goes

What would have to be true

  • full-ship, multi-port planning works;
  • these rates hold worldwide;
  • the extra work is avoidable;
  • terms that permit operational use: today's Muse Glimmer usage policy prohibits use related to operating transportation technologies where harm is possible, so a deployment would need Meta's permission or a base model whose terms allow it, plus class approval;
  • none of it has been measured.

Today's pilot runs the loop on synthetic half-ship sections of 500–800 TEU feeders. The path is more compute for the search and a larger model for reading, toward 1,700, 8,000 and 20,000 TEU ships (projection). The engine isn't competitive at large scale yet. This is a gross opportunity scenario, not a saving achieved.

Sources: docs/impact.md (exposure, pool, Laem Chabang projection, terminal-revenue check, what must be true; D254, D256, D316); experiments/mvp/ui/fixtures/film-figures.json (/figures/impact_low_billion, impact_teu_m, impact_calls_k, impact_restow_pct, impact_lift_usd, impact_berth_pct, impact_revenue_low, impact_revenue_high, impact_port_musd, stake_calls).

What the planner hands the master

Stored plan, computed on 2 Nov 2026, checked on 2 Nov 2026 · synthetic ships and cargo, simulated port · our own signature, not a certificate

The bay-nine hero: one sentence over the radio, "Nothing goes into bay nine on this call.", read on the laptop by StowLM Reader, then planned by Engine 0.13.0 and passed by the full checker. The handover package that comes out holds:

  • Bay plans, one printed A3 page per planned bay: 87 boxes in 6 of 12 bays of a half-ship section, beside 168 fixed synthetic background boxes.
  • The crane sequence and yard sequence, as CSV files.
  • A note to the master with the stability figures, dangerous-goods and reefer slots, the tightest limits, and the confirmed instruction.
  • A signed receipt tying each step to its model, hash and checker verdict. The signed package names the frozen pipeline it came from (v4, acf2f275…). It's our own signature, not a certificate.

The instruction is printed in the note to the master: "Confirmed instruction: Nothing goes into bay nine on this call. Confirmed by: user-authorised batch regeneration, no planner present (demo fixture)." The user authorised the batch rebuild; no planner confirmed it live.

Open the printed bay plan (PDF, 6 pages, 3 MB)

Source: experiments/mvp/pipeline/package/fixtures/hero-run/package/bay-plan.html, printed by experiments/mvp/pipeline/package/print_check.py (6 bay pages, 143 cell labels, no overflow, no console errors, no remote requests); note: note-to-master.md in the same folder. 3.1 was measured on frozen pipeline v3 (a11b4202…); the demo and package run on v4 (acf2f275…), which changes only the package and freeze code.