Home graph showing explicit objects, relationships, and state for Work, Environment, Home, Door, Tv, and TvChannel.
The explicit Home map shows one canonical structure for objects, relationships, state, and operations.

The fragmentation problem

Most teams do not model one system once. They rewrite the same world across ontology, API contracts, backend logic, client models, SQL layers, and docs. Every rewrite introduces another place for drift.

The Object Config Graph gives those surfaces one structural agreement in the middle instead of one truth per layer.

In practice, that agreement is first used to define the world model itself. In Aware, that world model is captured as an ontology: the explicit definition of what exists, how it relates, how it is identified, and which operations are valid.

OCG drives ontology: the world model

Here is the Home ontology:

home.aware
class Home {
    doors Door[]
    tvs Tv[]
    name String = "My Home"

    fn build construct (name String key = "home") -> Home {
        let created = construct Home(name = name)
    }

    fn add_door (label String, is_locked Bool = true, is_open Bool = false) -> Door {
        let created = construct doors.create(
            label = label,
            is_locked = is_locked,
            is_open = is_open,
        )
    }

    fn add_tv (name String = "living-room-tv", is_on Bool = false) -> Tv {
        let created = construct tvs.create(
            name = name,
            is_on = is_on,
        )
    }
}

This source shows what the OCG actually models in software. It makes object types, attributes, relationships, identity, and valid operations explicit in one place.

  • Class: Home, Door, Tv
  • Attribute: name
  • Relationship: doors, tvs
  • Function: build, add_door, add_tv
  • Identity: name String key = "home"
  • Enum: first-class when the model needs constrained values

Map, projection, territory

The authored ontology is the map of what can exist. To become runtime authority, the map needs a scoped projection and a live territory.

Map Authored ontology
Projection Scoped slice
Territory Live structure

The map defines what can exist. The projection selects the part that matters for one experience. The territory is the live structure and state that a client actually operates on.

home_projection.aware
projection Home is_branchable {
    root home.Home

    home.Home::doors
    home.Home::tvs
    home.Tv::channels
    home.Tv::active_channel

    observable security instance default {}
    observable entertainment instance {}
}

This projection does not create a second world. It selects the meaningful scope of the map that later becomes a live Home territory.

Territory view of the Home scene showing the live instantiated room and explicit state derived from the same scoped structure.
The territory is not a second model. It is the same scoped Home structure instantiated as live objects and state.

The .aware grammar

Everything shown so far, the ontology and the projection, is authored in .aware.

.aware is the grammar Aware uses to declare structural and semantic contracts. Today it expresses ontology, projection, API packages, and bindings. It is the surface developers start from, and it is the authored surface the Aware SDK is packaging for public use through the Graph-OS CLI bundle.

That matters because the graph is not inferred from Python, Dart, or SQL after the fact. The contract is written directly, then lowered into those surfaces.

OCG drives API: the capability boundary

Ontology is one application of .aware and OCG. The same mechanism also models the capability boundary.

An API boundary needs a named capability, a request shape, and a binding onto one canonical object and function. In Aware, that is authored directly in .aware too.

home_devices.apis.aware
api home_devices {
    capability lock_door {
        endpoint lock_door aware_home_api.door.LockDoor {
            """Lock a door by label inside the home graph."""
        }
    }

    capability unlock_door {
        endpoint unlock_door aware_home_api.door.UnlockDoor {
            """Unlock a door by label inside the home graph."""
        }
    }

    graph aware_home {
        projection aware_home.home.HomeProjection {
            binding aware_home_api.door_by_label Home::doors
        }

        capability lock_door {
            function lock aware_home.home.Door.lock
        }

        capability unlock_door {
            function unlock aware_home.home.Door.unlock
        }
    }
}
  • api: declares the capability surface
  • capability: names one operation the surface offers
  • endpoint: binds that operation to a DTO type
  • graph: binds the capability to the ontology function that actually runs

The important shift is not that Aware generates API code. The important shift is that the API contract is carried by DTOs, and those DTOs are modeled via OCG. ORM models stay where runtime mutation happens. DTOs cross the boundary. Both are canonical, and they are not the same thing.

door/endpoints.aware
class LockDoor {
    label String
}

The endpoint type itself starts in .aware, not in a handwritten Python or client package.

Generated Python DTO
class LockDoor(BaseModel):
    label: str = Field(description="Door label used to select the target door.")

The repo proves that lowering directly today on the Python API surface. Dart is already lowered from the same graph on the ontology and client surfaces shown later in this chapter. That is the honest current scope: one authored contract, Python API DTO proof today, and shared graph lowerings already spanning backend, client, and SQL surfaces.

Contract surfaces

Once ontology and API are authored against the same graph contract, Aware can lower that contract into operational surfaces without introducing parallel truth.

.aware Authored source
Source OCG Compiler IR
Runtime OCG Persisted graph truth
Lowered surfaces Python / Dart / SQL

Honest boundary: in the current Aware direction, .aware is authored source, source OCG is compiler IR, and runtime OCG is the persisted graph truth. SQL is not the durable truth rail.

Python: runtime mutation and API DTO surface
Python
class Home(ORMModel):
    doors: list[Door] = Field(default_factory=list, exclude=True)
    tvs: list[Tv] = Field(default_factory=list, exclude=True)
    name: str = Field(default="My Home")

    async def add_door(self, label: str, is_locked: bool = True, is_open: bool = False) -> Door:
        payload = {"label": label, "is_locked": is_locked, "is_open": is_open}
        result = await invoke_instance(orm_model=self, function_name="add_door", payload=payload)
Dart: compiled data model and invocation surface
Dart Model
@freezed
abstract class Home with _$Home {
  @JsonSerializable(explicitToJson: true, fieldRename: FieldRename.snake)
  factory Home.def({
    @UuidValueConverter() required UuidValue id,
    @Default(const []) List<Door> doors,
    @Default(const []) List<Tv> tvs,
    required String name,
  }) = _Home;
}
Dart Functions
extension HomeFunctions on Home {
  Future<Door> addDoor({
    required FunctionInvocationContext context,
    required String label,
    required bool isLocked,
    required bool isOpen,
  }) async {
    final request = FunctionInvocationRequest(
      objectType: 'home',
      objectId: id,
      functionName: 'add-door',
      threadId: context.threadId,
      branchId: context.branchId,
      projectionHash: context.projectionHash,
    );
  }
}
SQL: branch-aware projection and index surface
SQL
CREATE TABLE home (
  branch_id UUID NOT NULL,
  projection_hash TEXT NOT NULL,
  id UUID NOT NULL,
  name TEXT NOT NULL,
  PRIMARY KEY (branch_id, projection_hash, id)
);

Here branch_id and projection_hash scope rows to one branch and one projection. The next chapter picks up that lifecycle in depth.

SQL is real and important here, but it is a projection/index surface aligned to runtime graph truth, not the durable truth rail itself.

Per-language responsibilities

Python carries the runtime mutation rail and the API DTO package this chapter can prove directly today, so live behavior and request-shape lowering execute against the same graph contract. Dart carries representation models and invocation surfaces, so clients can operate against that contract without re-modeling it by hand. SQL carries branch-aware projection and index storage, so queryable surfaces stay aligned to runtime graph truth instead of replacing it.

Why this matters now

The strongest product read is not that Aware can generate artifacts in multiple languages. It is that one ontology and one API boundary can stay canonical to the same contract.

That is a path away from ontology drift, API drift, and backend/client mismatch. It is also a path toward one authored contract for structure and capability, cross-surface lowerings that do not need synchronized rewriting, and one explicit system for humans and agents to operate on together.

What comes next: actors, functions, commits

OCG answers the structure question. The next question is change: who acts, which function runs, what changes in the object instance graph, and how commits make that evolution attributable and replayable.

This chapter proves canonical ontology, canonical API request shapes, and canonical DTO/binding emission today. The later API-to-service-to-actor rail belongs in the sequel, not here.

Shared Digital Reality remains the opening chapter. The next product chapter is actors, functions, OIG, and commits.

Continue The Narrative

Follow the chapter ladder

Start with the thesis if you want the broader worldview. Stay on aware.run if you want the next product chapter on change and commits.

Browse the full Aware publication history