Item B (slice-1 fix round). A LoadEmbeddedNavigationRoute action carried
a synthesized "uTank2 NAV 1.2" TEXT blob in MetaAction.Text that both
MetaEngine and the runtime consumer (MossTankPanel) had to re-parse on
every load — an unnecessary re-parse of already-typed data, and the
reason proof (3)'s AssertActionsEqual skipped comparing embedded routes
entirely (the blob's exact byte shape wasn't a meaningful comparison
target).
- MetaAction: new EmbeddedRoute (NavigationSettings?) property replaces
the blob. Null only for a genuinely unresolved/never-defined Nav tag.
- MetaServices.LoadEmbeddedNavigationRoute: Action<string> ->
Action<NavigationSettings?>; MetaEngine's dispatch passes
action.EmbeddedRoute directly.
- MetafSerializer.ResolveEmbeddedNavs (.af importer) builds the
NavigationSettings directly via the existing ApplyNavBody helper
(renamed SynthesizeNavBlob -> BuildNavSettings) instead of serializing
it back into text. WriteBinaryNavBlob/WriteBinaryWaypoint/
FormatBinaryDouble are deleted outright (the only caller was the
now-removed blob synthesis).
- SaveMeta had its own now-dead re-parse of action.Text via
VtankNavRouteSerializer.TryLoad to rebuild each embedded NAV: block on
save; this silently started producing EMPTY NAV: blocks once Text
stopped carrying the blob (Text is now always cleared for this action
kind), caught immediately by the full suite: MetaParseWriteParseIsIdentical
started failing "Expected: Once / Actual: Circular" (a re-parsed route
falling back to NavigationSettings' default Mode because its NAV: block
vanished). Fixed by writing straight from action.EmbeddedRoute.
- VtankMetaProfileSerializer (.met importer): TryLoad gained an
ISpellCatalog overload (threaded through ReadAction/ReadEmbeddedNavigation);
ReadEmbeddedNavigation now parses its reassembled blob text through
VtankNavRouteSerializer.TryLoad into a real NavigationSettings instead
of handing the raw text to the caller. The existing 2-arg TryLoad
overload defers to MetafSerializer.NoOpSpells.Instance (promoted from
private to internal) so both test call sites and MossTankMetaProfileStore
(which now passes _host.Automation.Spells) keep working.
- VtankNavRouteSerializer.Apply promoted from private to internal so
MossTankPanel.LoadEmbeddedNavigationRoute can copy an already-typed
NavigationSettings into the live _navigationSettings instance directly,
replacing its own VtankNavRouteSerializer.TryLoad(string, ...) re-parse.
- MetafSerializerTests: AssertActionsEqual now asserts
EmbeddedRoute is non-null on both sides and calls AssertNavigationEqual
on them (waypoint-by-waypoint) for LoadEmbeddedNavigationRoute actions,
instead of skipping the comparison. PtlNodeKeepsBothCoordinateTriplesDistinct's
FindNavWaypoint helper reads action.EmbeddedRoute directly instead of
re-parsing action.Text (which is now empty).
Full MossTank suite: 568/568 passing (net zero change in count — this
is a representation change, not new coverage, though the AssertActionsEqual
tightening now exercises real waypoint comparisons on every fixture with
an EmbedNav action that it previously skipped).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>