Cohesive Systems logoCOHESIVE SYSTEMS

Search Cohesive Systems

Ready

Search Cohesive Systems

Find product pages, building blocks, technical articles, and graph definitions.

From Software Factories to Semantic Systems

By Leo GorodinskiPublished Jul 30, 2026

Software engineering advances by changing what people have to author directly. Machine instructions gave way to symbolic programs, then languages, libraries, managed runtimes with garbage collection, frameworks, platforms, and models. Each wave let developers state more of what they wanted while delegating more of how it would happen.

Software factories were an ambitious step in that progression. They tried to capture reusable production knowledge in domain-specific languages, product-line assets, frameworks, generators, and tools. Their critics correctly saw the danger: a model can become another brittle artifact, a generator can become an opaque authority, and a factory can optimize the production of systems without helping those systems remain intelligible as they evolve.

AI changes the balance again. It can produce system artifacts without every variation having to be anticipated in a code-generation pipeline. But cheap implementation does not eliminate the need for an authoritative semantic artifact. It changes what that artifact must contain: the system's semantic commitments—its accepted account of what exists, how it may behave, what must remain true, who has authority, and which operational properties every realization must preserve.

The Authored Boundary Keeps Moving

The familiar history of software is often told as a ladder of increasingly powerful notations. The crucial property of each rung is the transfer of responsibility it enables: something below accepts responsibility for the details that the programmer no longer writes.

An assembler resolves symbolic names into addresses and instructions. A compiler selects instruction sequences and representations. A database accepts responsibility for storage structures, indexes, concurrency, and recovery under a declared recovery model. A cloud platform assumes responsibility for placement, restart, routing, and scaling. The abstraction is not merely a shorter way to say the same thing. It precisely reassigns responsibilities among system participants.

Cool-gray pencil sketch of a ladder rising from machine instructions through managed runtimes and garbage collection, platforms and product lines, software factories, and AI-generated implementation toward semantic systems, stopping below an open sky.
Each rung delegates a larger class of implementation decisions to the substrate. The progression overlaps rather than replacing the layers below.

This is why the history is better understood as a rising sea. Machine instructions remain below the working surface established by high-level languages. Each new layer succeeds when most developers can reason above it while specialists can still inspect and improve what lies below.

The boundary has never moved uniformly. Systems programming still exposes memory layout. Databases still allow physical design. Frameworks expose escape hatches. Every abstraction is a negotiated transfer of control, not a promise that lower layers no longer matter.

The Rising Sea of Responsibility

Garbage collection is a particularly clean example. It did not make object lifetime, heap pressure, or reclamation disappear. It transferred the ordinary proof of when memory could be reclaimed from each application author to a language runtime and collector.

That transfer changed what programmers could safely assume. They could compose object graphs and return references without threading explicit deallocation through every interface. The runtime paid for that freedom with tracing, generations, barriers, compaction, pauses, and new failure modes. As the LLVM documentation puts the responsibility plainly, garbage collection belongs to the language's runtime rather than LLVM itself.

The lesson is not that automatic memory management is always preferable, but that when it is used, the associated management responsibilities must be clearly delegated to the runtime.

Clear delegation, in turn, requires a deeper understanding of the responsibility being transferred. When the work is performed by hand, its governing concepts can remain tacit, scattered across local decisions, or go unnoticed. A reusable abstraction must identify and formalize those concepts well enough to state what is delegated, what remains with the application, and which guarantees hold at the boundary.

Compiler

Responsibility Delegated
Instruction selection, register use, representation, and calling details.
What Must Be Formalized to Delegate Safely
Source and target semantics, calling conventions, correctness-preserving transformations, and diagnostic behavior.

Garbage-collected runtime

Responsibility Delegated
Determining when ordinary managed objects may be reclaimed.
What Must Be Formalized to Delegate Safely
Reachability, roots, object lifetime, finalization, safepoints, and latency and throughput behavior.

Database

Responsibility Delegated
Physical storage, access paths, concurrency, durability, and recovery.
What Must Be Formalized to Delegate Safely
Data and transaction models, isolation, commit semantics, failure assumptions, and recovery guarantees.

Cloud platform

Responsibility Delegated
Placement, restart, routing, scaling, and health management.
What Must Be Formalized to Delegate Safely
Desired state, topology, scheduling constraints, health signals, failure detection, and service guarantees.

Software factory

Responsibility Delegated
Repeated assembly of systems within a known family.
What Must Be Formalized to Delegate Safely
Commonality and variability, asset roles, production rules, extension boundaries, traceability, and consistency obligations.

AI implementation agent

Responsibility Delegated
Syntax, scaffolding, translation, and local adaptation.
What Must Be Formalized to Delegate Safely
Accepted intent, authoritative context, constraints, permissions, uncertainty, and validation and conformance criteria.

This distinction matters for Cohesive. Moving upward should not mean hiding semantic obligations inside a generator. It should mean authoring those obligations explicitly while transferring their implementation to compilers, runtimes, infrastructure, and agents that can be checked against them.

What Software Factories Got Right

Software factories tried to apply this logic at the scale of system families. Repeatedly constructing similar systems by hand wastes more than keystrokes; it wastes production knowledge. Factory approaches sought to capture that knowledge in reusable forms that could guide the construction of each member of a system family.

Software factories brought together ideas and mechanisms from domain-specific languages, model-driven engineering, software product lines, application frameworks, code generation, templates, configuration systems, and integrated tooling. Together they support the ambition of capturing the stable structure and meaningful variation of a system family so that systems within the family can be produced consistently.

The Software Engineering Institute describes a product line in terms of common assets used in a prescribed way, supported by a production plan. Its product-line framework makes clear that the assets are not only code. They include architecture, components, tests, tools, processes, and organizational capabilities.

That is the enduring insight of the factory idea:

  • A system is produced from more knowledge than appears in its source files.
  • Variation should be explicit rather than scattered across forks and conditionals.
  • Frameworks and platforms embody architectural decisions whether or not those decisions are modeled.
  • Production rules can preserve consistency across code, schemas, configuration, tests, and deployment artifacts.
  • A family of systems can justify richer tools and languages than a single application can.

Factories tried to elevate reusable production intent over repeated manual assembly. That direction was right. The difficulty was deciding what deserved to become the durable model and how that model could survive contact with an evolving system.

Why the Pushback Was Right Too

Some pushback against software factories and model-driven development came from familiar resistance to working at a higher level of abstraction. Projects also encountered high upfront costs, specialized toolchains, awkward generated code, model-code drift, and models that were either too generic to be useful or too narrow to survive the next requirement.

The factory model also changed how authority and responsibility were distributed. It can concentrate design authority in the team that owns the generation pipeline while leaving other teams dependent on its outputs. When the generated system misbehaves, the people responsible for it may be forced to debug an artifact they were discouraged from understanding or changing.

Industry studies found a more nuanced reality than either triumph or failure. Whittle, Hutchinson, and Rouncefield's study of 450 practitioners and 22 interviews reported that model-driven engineering was commonly applied to important parts of systems rather than to whole-system generation. Their state-of-practice report and related industrial case studies emphasize incremental adoption, integration with existing work, clear business purpose, and organizational change—not only better modeling tools.

Any successor to the factory model must incorporate these lessons into its design.

One universal model

Requirement for What Comes Next
Preserve the distinct semantics of different concerns while defining explicit relationships among them.

Lost model-realization correspondence

Requirement for What Comes Next
Keep models and realization artifacts in typed, versioned correspondence, with traceable identity, revisions, target assumptions, and conformance checks.

Value arrives only after a platform rewrite

Requirement for What Comes Next
Support incremental adoption through reviewable slices that can coexist with brownfield artifacts.

Opaque generated artifacts

Requirement for What Comes Next
Make transformations deterministic, inspectable, and traceable from their source definitions to each generated or selected mechanism.

Vendor or toolchain lock-in

Requirement for What Comes Next
Keep authored definitions portable and vendor-neutral, support external compilation targets, and treat Cohesive itself as a potential source of lock-in.

Variation must be predicted in advance

Requirement for What Comes Next
Let models and languages evolve through versioned extensions rather than treating a system family as closed.

Factory builders own all important decisions

Requirement for What Comes Next
Make authority, proposals, approvals, and responsibility explicit and reviewable.

A successor to the factory model therefore needs a durable account of system meaning that can accept new commitments without losing the meaning already established.

Software Is Evolved, Not Manufactured Once

The factory metaphor is strongest at the moment of production: assets enter, rules are applied, and a product emerges. Long-lived software spends relatively little of its life at that moment. It is interpreted, operated, repaired, extended, migrated, and renegotiated in an environment that changes around it.

M. M. Lehman's account of E-type programs—software embedded in and judged by a real-world activity—makes evolution intrinsic rather than exceptional. His laws of software evolution describe continuing change and increasing complexity as persistent pressures on useful systems. The exact formulations have been refined and debated, but the central observation remains: successful software and its environment continually act on one another.

When production is one event in a much longer system life, the durable model must describe continuity and change as well as construction.

A traditional factory asks how to produce another member of a known family. A durable system model must also preserve identity and conceptual integrity while the family, the product, the production machinery, and the environment all change. It needs versioned claims, explicit compatibility and evolution, semantic deltas, migration relationships, and evidence about whether current realizations still conform.

This does not reject production automation. It places production inside a larger lifecycle. Generation is one consumer of meaning. Analysis, migration, verification, agent context, operation, and conformance are others.

AI Raises the Waterline Again

Traditional generators are powerful where variation can be anticipated. They encode a bounded family: given these inputs and extension points, produce these artifacts. AI is different. It can infer a local pattern, adapt to an unfamiliar repository, translate between conventions, and synthesize a variation that no factory author enumerated.

AI can therefore accept implementation responsibility across a much wider range of variation. That transfer increases the need for an explicit account of the system being changed, the intent of the change, and the authority under which it may proceed.

As argued in Commoditizing Determinism, AI lowers the cost of syntax, scaffolding, and local change while increasing the relative value of trusted system understanding. A model can produce plausible code from the context it receives. It cannot decide by fluency alone which contradictory artifact is authoritative, which invariant was intentional, which exception may be generalized, or who may approve a change.

The old factory bottleneck was the cost of anticipating and encoding variation. AI relaxes that bottleneck. The new bottlenecks are comprehension and intent specification:

Comprehension

Question
What does the current system mean, and which account is authoritative?
Why AI Does Not Remove It
AI can infer a model from artifacts, but the artifacts may be incomplete, stale, contradictory, or merely observational.

Intent specification

Question
What change should the system accept, under which constraints and authority?
Why AI Does Not Remove It
AI can propose intent, but acceptance is an organizational and semantic commitment rather than a prediction problem.

These bottlenecks are coupled. Weak comprehension makes intent underspecified; underspecified intent forces every implementation agent to reconstruct policy from local clues. A durable model breaks that loop by letting understanding accumulate and new intent arrive as a delta over accepted meaning.

Once a change has been accepted, realization becomes a governed search for mechanisms that satisfy it. AI can produce candidates, while capability matching, verification, provenance, and conformance determine whether those candidates are suitable.

The Next Authored Artifact

The movement from instructions to languages, runtimes, frameworks, factories, and AI has steadily reduced the amount of implementation people must author directly. It has not reduced the need to decide what the system means.

That meaning includes:

  • identity
  • relations
  • state
  • transitions
  • processes
  • invariants
  • authority
  • effects
  • boundaries
  • operational requirements
  • projections
  • evidence

These commitments outlive any particular class hierarchy, framework, database, cloud, interface, or generated patch. They are the stable subjects against which implementations can vary and evolution can be reviewed.

Program

Strength
Precise executable behavior.
Characteristic Limit
System meaning remains distributed through implementation choices and external artifacts.

Factory model

Strength
Repeatable production across anticipated variation.
Characteristic Limit
The model can become closed, generator-centric, or detached from the evolving realization.

Natural-language prompt

Strength
Fast, flexible expression and adaptation.
Characteristic Limit
Intent is contextual, ambiguous, and difficult to accumulate as an authoritative system history.

Semantic system definition

Strength
Versioned meaning that can drive and constrain many projections.
Characteristic Limit
Requires explicit language design, governance, interpretation, and evidence—not only generation.

The next abstraction is therefore not a universal programming language or a more comprehensive factory schema. It is the definition of the system as a connected set of semantic commitments, authored through appropriate system languages and interpreted into many artifacts.

A semantic system is one whose accepted meaning is represented as a durable, versioned definition and kept in explicit correspondence with the artifacts that realize it.

Those artifacts remain indispensable. Code executes. Databases persist. Interfaces mediate human action. Infrastructure fails in physical ways. AI proposes and implements changes. Implementation artifacts become projections of the semantic definition. Runtime observations and conformance results provide evidence about whether its realizations preserve the accepted commitments.

Making semantic commitments first-class requires a representation that can connect their identities, relations, versions, mappings, and evidence. Cohesive calls the complete, connected, versioned model of these commitments, mappings, and evidence a semantic system graph.