The Container Is the Composing Agent
Whenever pieces become one larger thing, somebody or something decides how they fit. In a document tree, a parent chooses where child regions appear. In a circuit, an owning region chooses which resources belong to a subcircuit and how its ports connect. In a distributed application, an orchestrator allocates processes and establishes routes.
That decision-maker is the composing agent.
The composing agent does not have to perform the work of every constituent. It controls the composition facts it owns: membership, placement, attachment, replacement, and release. Once two constituents have a connection, their ordinary exchange can be peer to peer.
This distinction prevents a common mistake. Composition authority and data-path authority are not the same thing. The program allowed to connect two streams does not need to sit forever in the middle of those streams.
One Composition Fact Needs One Owner
Several composers can exist in one system. They do not even need to form one clean global hierarchy. What they cannot safely do is make independent, conflicting decisions about the same port, region, or connection without a protocol that orders those decisions.
If two agents can simultaneously decide what occupies the same space, the result is not rich decentralization. It is an unresolved write conflict.
Ownership makes the conflict local and answerable:
- Who may allocate this region?
- Who may install a new program here?
- Who may expose or connect this port?
- Who may cut, redirect, or release the connection?
- When does transferred authority take effect?
A system can transfer ownership, subdivide it, or represent it with a tree. The essential point is that every mutation has an authorized origin and a defined completion moment.
Composition Arrives as a Stream
A physical channel cannot deliver an entire new structure at once. It delivers a sequence of symbols in time. Even a wide bus has finite width. Even a shared-memory update reaches different storage elements through finite circuitry.
The composition channel is therefore a stream of small changes: allocate, describe, connect, initialize, commit, release. A receiver may collect several changes in private staging state and make them visible together, but the collection itself still arrived piece by piece.
This makes transaction boundaries important. While a replacement is arriving, the old program may still be active. The new description must not leak into the application plane as a half-old, half-new structure. Installation needs a completion condition and an apply step.
In Cartilage I make this distinction concrete. A bounded child region receives configuration records through a local reconfiguration port. The records are collected through the region’s ownership route, and an apply event installs the new cell roles. Configuration is not a magical rewrite from outside the model; it is traffic carried and retained by the same kind of cells that later perform the application computation.
Placeholders Are Ownership Boundaries
User-interface systems expose the same problem in softer material. A parent view may determine the frame around a child while the child owns the contents inside that frame.
The parent should describe the structure it owns and leave an attachment place for the child. Updating the parent must not silently replace the child’s private subtree. The placeholder is not an empty visual trick. It marks a resource boundary.
This is where a fully unrolled virtual tree becomes expensive and misleading. If every parent repeatedly reproduces a complete description of all descendants, descriptions grow with the runtime structure and ownership becomes fuzzy. A small local change can cause a large tree to be regenerated only so a patcher can rediscover that most of it stayed the same.
A compositional description can stay smaller by carrying types, parameters, identities, and attachment points. Constituents then maintain their own state and update through their own channels. The larger view is assembled from independently owned regions rather than recopied as one giant value.
Private State Is a Program
In this model, “value” does not have to mean a passive record that another machine interprets. A value can contain state, Boolean structure, and the ability to respond to incoming signals. It is an active program.
The program’s internal value remains private. Other programs do not obtain it by reaching through the boundary and reading arbitrary fields. They learn what the program chooses to communicate. They send messages, receive messages, and build their own internal models of one another.
This is more general than observable properties and callbacks. A one-bit channel can carry a language over time. With framing and a shared protocol, a narrow connection can describe structures far larger than one bit. The channel does not expose the whole state surface. It carries a conversation from which each side updates private state.
Reactive propagation then has an ordinary meaning: when a private state changes, relevant conversations follow. Connected programs do not need a global caller to walk the whole system and ask every value whether it is now stale.
Code, Deployment, Program
Three terms separate a description from its use:
- Program code
- A complete streamable description sufficient to initialize one program’s structure and state.
- Deployment
- The process of carrying that description to an allocated place and installing it there.
- Program
- The installed active instance with private state and communication channels.
A program can be produced from a fixed snapshot, generated from parameters, or copied from a captured state. The constructor is not a remote invocation of a disembodied class. It is a deployment operation that consumes channel capacity, space, and time.
A composite program represents a distributed value by coordinating constituent programs. It does not need to flatten their private state into one record. Its own state includes the composition facts: which constituents exist, which resources they occupy, and how their channels are connected.
Unallocated Space Is Not Nothing
Space that can accept a program already has behavior. It must be locatable. It must receive an allocation request. It must establish a configuration path, collect a deployment stream, decide when installation is complete, and yield control to the new program.
That makes unallocated space a program too.
A minimal deployment conversation looks like this:
- An owner requests enough adjacent space for a new program.
- The space manager identifies a bounded region and an attachment point.
- The owner establishes a configuration route to that region.
- The code stream travels through the route into staging state.
- The region reports that the complete description has arrived.
- An apply event installs the new roles and initial state.
- The owner connects the new program’s application channels.
I have built the bounded case in Cartilage: installation through a child-owned local port. The next layer is a general allocator that can find arbitrary space, transfer ownership, relocate ports, and reconnect a live program. I want that layer built from the same explicit operations rather than smuggled into the word “instantiate.”
One Bit Is Enough to Talk, Not Enough to Carry Everything
A narrow channel is sufficient for arbitrarily rich descriptions given enough time. It does not follow that one shared narrow channel is a sensible path for every data flow in a large composition.
Imagine an owning program with many constituents. If every message between every pair must enter the owner, be decoded, be addressed again, and leave through the same one-bit opening, the owner becomes a serialization machine. Internal parallelism collapses onto one contested route. Faster serializers can raise the ceiling, but they do not remove the topology.
bad:
A --\
B --- owner / relay --- external peers
C --/
better:
owner establishes A <--> B
owner establishes B <--> C
application traffic follows those direct channels
Encapsulation should protect authority and private state. It should not force the owner to proxy all constituent bandwidth. The scalable rule is simple:
Manage connections. Do not relay every conversation.
This is as relevant to servers and accelerators as it is to a reconfigurable fabric. A control plane may allocate endpoints and authorize a path while a data plane carries the high-volume stream directly.
How Cartilage Makes the Model Physical
Cartilage is my homogeneous two-dimensional fabric. A finite cell record selects a working role such as wire, constant, crossing, multiplexer, or reconfiguration port. Additional state identifies local ownership and carries the configuration transaction.
A parent region can maintain a bounded daughter region through a port that belongs to the daughter’s ownership tree. A serial configuration stream changes the daughter’s actual cell roles. The result is not an object drawn over a circuit. It is a new circuit installed into the same substrate.
The nested-instantiation article and live machine let you watch the spatial idea happen. Cartilage Core follows one installation in both a compact browser model and an independent SystemVerilog model. The Boolean construction gives the formal route through finite owned regions, local ports, installation, commit, and release.
The next layer is placement, reclamation, arbitrary connection routing, live migration, and general program generation. Each one must become an algorithm carried by the fabric, with its state and authority visible in the same model as the circuit it changes.
Rules for a Reactive Composer
- Give each mutable composition fact an explicit owner.
- Keep constituent state private; communicate through defined channels.
- Represent installation as a finite stream with completion and apply phases.
- Make attachment points first-class resources.
- Treat unallocated space as an active participant in allocation.
- Separate the control path that establishes a connection from the data path that uses it.
- Do not regenerate or proxy structure that another program already owns.
- Measure channel contention before declaring a narrow interface elegant.
The result is not object-oriented software poured into hardware. It is a common language for composition wherever state has a place, change takes time, and one active structure creates another.