Skip to main content

Migration And Anti-Patterns

Most Morph mistakes look convenient in the short term.

They become expensive when the framework grows.


Common Anti-Patterns

These are the patterns to watch for:

  • feature behavior implemented directly in core as a shortcut
  • package runtime code moved into generic runtime folders
  • package command behavior wired directly into core CLI
  • provider assumptions left undeclared
  • build or execution behavior hidden in manual wiring
  • domain knowledge (tokens, type names, syntax forms) hardcoded anywhere in src/ \u2014 the most dangerous leak

The Core Leak Anti-Pattern

A Core leak is any case where src/ files contain knowledge that belongs exclusively to packages.

Examples of leaks:

// LEAK \u2014 src/parser/ParseDeclarations.cpp
if (token == "is") { /* ... */ } // Token knowledge in Core

// LEAK \u2014 src/sema/ExpressionAnalyzer.cpp
if (typeName == "Int") { /* ... */ } // Type knowledge in Core

// LEAK \u2014 src/codegen/LLVMCodeGen.cpp
if (node->kind == NodeKind::Tensor) { } // Domain concept in Core

The correct form: Core receives opaque plugin-dispatched facts. It never inspects token surfaces, type names, or construct identities by name.

// CORRECT \u2014 Core dispatches to the plugin that owns the semantic family
morphSemaRuntime.dispatch(surfaceView, context); // Core knows nothing about what this does

If you find a match on a keyword string, a type name, or a construct-specific enum value inside src/ while implementing a feature: stop. Move that knowledge to the package that owns the concept. If no hook exists yet to support the move, widen the framework \u2014 but never leave domain knowledge in Core as a shortcut.


The "Just This Once" Trap

The most dangerous Morph mistake is:

"We will hardcode this one in core for now."

That usually turns into permanent ownership drift.

If a package cannot express the feature, fix the framework surface immediately instead of creating a temporary core shortcut.


Migration Rule

When moving an existing behavior into Morph:

  1. identify the true package owner
  2. move declarations into manifests
  3. move implementation into package folders
  4. widen framework APIs only where the package genuinely needs it
  5. add boundary tests so ownership does not regress

Smells That Mean You Need A New Package

You probably need a new package when:

  • an existing package boundary becomes unclear
  • a feature needs unrelated runtime and tooling semantics
  • the package's README would need a long apology section to justify the addition

Distinct ownership deserves a distinct package.


Smells That Mean You Need Framework Work

You probably need framework or SDK widening when:

  • the manifest cannot declare the needed relationship
  • the public SDK cannot describe the needed callback or descriptor
  • generated glue cannot wire the package behavior cleanly

That is the correct time to change the framework.


Next Steps