Composition & references

Linking across files

Connections link properties inside one document. Composition links across documents: a prim can reference another .prisma/.prism file and pull its subtree in at that point. Model a thing once; reference it many times; fix it in one place and every use updates.

def group "garage" {
    def object "car1" { reference = "car.prisma" }
    def object "car2" { reference = "car.prisma" }   # the same model, twice
}

A reference is reserved metadata on a prim naming another document (and, optionally, a path inside it). Nothing is copied at author time — the link is recorded; resolution happens when you ask for the composed document.

Resolving

compose walks the references and returns one flattened Document with every referenced subtree pulled in:

Document flat = composeFile("garage.prisma");        // resolves relative paths on disk (trusted input)

For environments without a filesystem — a server, a sandbox, a bundle — the portable entry point resolves against any resolver you supply, so composition works against in-memory documents just as well:

Document flat = compose(doc, Path("/garage"), [&](std::string ref) -> std::optional<Document> {
    return lookUpSomehow(ref);                     // you decide where bytes come from
});

From the CLI:

prism compose garage.prisma > flat.prisma          # references resolved, one Document

Local opinions win

A referencing prim can override properties of what it pulls in: local values take precedence over referenced ones. That is what makes shared assets practical — reference the standard car, then override its colour on car2 without forking the file.

A safe, memoized DAG

References can be transitive (a referenced document may reference others), forming a directed acyclic graph. Resolution memoizes each document, so a diamond — two prims referencing the same file — loads it once rather than exponentially. Cycles are rejected rather than followed, and a missing reference is a clean, located error, not a crash.

Why it matters

Linking instead of copying is what turns a folder of files into a connected project — and what lets a program or an agent operate at the level of intent. "Swap the shared material to the blue one" is a single edit to one referenced document, not a search-and-replace across dozens of files that might miss one. Connections and composition are the same idea at two scales: identity is a path, and a link is just another path — within a document, or across them. That principle is also what makes a directory tree expressible as a Document, which is the basis of bundles.