Skip to content

Schema: bounded contexts — model scope slugs and cross-model references #25

Description

@jbeda

A system outgrows one model. Splitting it is usually correct: different parts have different lifecycles, different owners, and sometimes one half gets open-sourced on its own. Today there is no way for one model to refer to an entity defined in another.

Checked against v1: the top-level keys are description, entities, enums, glossary, invariants, kind, scenarios, title, version. kind is a file-type discriminator (always DomainModel) and title is display-only, so nothing there identifies a model or lets one reference another.

The situation

Two models in one organisation. One describes a development methodology and the artifacts it produces. The other describes a build tool that consumes those artifacts. They are deliberately separate: the second is intended to be usable by teams who have never adopted the first.

They share exactly one small piece of vocabulary — a three-value enum — because the methodology model needs to say where a rule is expressed, and the tool model needs the same three names for its own purposes.

The workaround, and why it is unsatisfying

Define the enum in both models and rely on the names matching. That works and it is what we are doing, so this is not blocking anything.

What it costs: the claim "these two enums are the same enum" lives only in prose. Nothing resolves it, nothing checks it, and the two definitions drift silently. That is the same shape as the gap #24 describes — the linter cannot check a claim the prose makes.

DDD framing

This is bounded contexts, and cross-context reference is normal rather than a smell. Evans names the integration patterns (shared kernel, published language, conformist, anticorruption layer), and a context map is the artifact that records which contexts exist and how they relate. A model that can name its own scope and import another's is the minimum needed to express any of that.

Proposed shape

  • Each model declares a scope slug at the top level.
  • A model may import other models.
  • References across a boundary are written scope-slug.EntityName.

Deliberately not proposed: prefix-alias mapping in the xmlns style. The slug is short already and an alias layer buys indirection rather than clarity.

What lint could then check

  • an import that does not resolve;
  • a scope-slug.EntityName reference where the slug is not imported, or the entity is not defined in that model;
  • import cycles across models, the same way subtypeOf cycles are caught today;
  • optionally, a local entity whose name shadows an imported one.

Render

The existing principle applies unchanged: the Mermaid ER is a deliberately lossy view and the Markdown is the source of truth. Imported entities could appear in a distinct section (or simply be marked as external where they are referenced) without the ER attempting to draw a context boundary.

Related: #24. Both are cases where the model's prose asserts something the tooling cannot verify.


🤖 Filed by Claude Code on behalf of a modelith user, from a real modelling session that hit this boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions