# Merge Conflicts

Lob is a separate, tensor-native version-control system that Tensormorph **anchors to** - it is not bundled, and Lob's own branch/merge model is not yet finalized. This page explains what a weight-space conflict *is* and the shape the resolution problem takes, drawing on git/GitHub's conflict model as the closest existing precedent. Treat the interaction flow described below as a design direction, not shipped UI.

## How Tensormorph anchors to Lob

Tensormorph doesn't store weight history itself. Instead, a loaded checkpoint carries a **commit pin** - a reference to the Lob commit it was materialized from - plus a content hash. If the underlying Lob history moves past that pin, Tensormorph detects the mismatch (a **stale-note**) and surfaces it, rather than silently comparing you against out-of-date history. Reviewing a proposed weight change from inside Tensormorph is referred to as reviewing a **weight-space pull request**: a Lob-side object that Tensormorph can load, diff, and annotate, even though Tensormorph itself doesn't perform the merge.

## What counts as a conflict

Unlike a text-based VCS, "the same region" isn't a line number - it's a tile address in a tensor. By analogy with git's own line-level-vs-structural split, a weight-space conflict is worth distinguishing along the same two axes:

-   **Numerically resolvable conflicts** - two branches changed the same tile or region by a small, distinct amount (two separate quantization passes, or two morph branches that both nudged the same attention head). In principle these could be resolved by a numeric rule - keep one side, or blend them - without touching the rest of the tensor.
-   **Structural conflicts** - the branches disagree on something a numeric rule can't paper over: incompatible shapes, a layer added on one side and removed on the other, or a dtype change only one branch made. These need a human decision about which architecture is correct, not an averaging function.

Whether two changed regions actually conflict is a [semantic-diff](/docs/core-concepts/model-diff) question, not a byte-for-byte one - two branches that touch the same tile but converge on the same value are not a conflict.

## What resolution could look like

GitHub's in-browser conflict editor - pick a side, or write something new, mark resolved, repeat per file - is the closest existing interaction pattern for the *resolvable* half of this problem, and it transplants reasonably well:

1.  Open the weight-space pull request and inspect the flagged tensors; each conflicting region is highlighted on a heatmap of both sides' values.
2.  For a numerically resolvable region, choose a resolution: keep one side's values, or blend them (matching whatever interpolation the originating morph used).
3.  For a structural conflict, no in-app resolution applies - the underlying change needs to be re-authored against a common base, which happens on the Lob side, outside Tensormorph.

What's genuinely undecided - and therefore not documented as fact here - is whether steps 1–2 ship as in-app actions that write back to Lob, or whether Tensormorph's role stays read-only (surface the conflict, hand off resolution to a Lob-native tool). Don't build against a specific UI for this until Lob's merge model is finalized.

## Related resources

-   [Weight Diff](/docs/compare-and-morph/weight-diff) - how a numeric diff between two commits is rendered, independent of whether it's conflicting.
-   [Model Interpolation](/docs/compare-and-morph/model-interpolation) - the interpolation math referenced by the "blend" resolution above.
-   [Model Diff](/docs/core-concepts/model-diff) - the semantic-diff machinery used to decide whether a region actually conflicts.
