From config to instances

The Object Config Graph defines what can exist — types, relationships, functions, constraints. The Object Instance Graph (OIG) records what actually happens. Every time a function is called, a record is created, or a relationship is modified, the OIG captures that mutation as a committed, attributed, hash-chained receipt.

Think of it this way: the OCG is the schema. The OIG is the ledger.

Anatomy of a commit

Every OIG commit is a self-contained record of what changed, who changed it, and how the graph state evolved. Here is the structure:

Commit structure
{
  "commit": {
    "id":             // Unique commit UUID
    "author_id":      // Who made this change (human or agent)
    "commit_parents": // Parent commit(s) — forms the DAG
    "created_at":     // UTC timestamp
    "lane_id":        // Stable lane (branch + projection)
    "status":         // local | synced | confirmed
  },
  "graph_hash_pre":   // SHA of graph state before
  "graph_hash_post":  // SHA of graph state after
  "projection_hash":  // Which projection this commit belongs to
  "changes": [        // Array of mutations
    {
      "type": "CREATE" | "UPDATE" | "DELETE",
      "class_instance_changes": [...],
      "class_instance_relationship_changes": [...]
    }
  ]
}

Key properties of every commit:

Field Purpose
author_id Attribution. UUID of the actor — human user or AI agent. Always present.
graph_hash_pre/post Hash continuity. The pre-hash of commit N must match the post-hash of commit N-1.
commit_parents DAG lineage. Linear history by default; branching requires explicit opt-in.
projection_hash Scoping. Ties the commit to a specific OPG projection (actor view).
lane_id Derived from branch + projection. Multiple projections per branch are supported.

The hash chain: tamper-evident by design

Every commit carries a graph_hash_pre and a graph_hash_post. The validation rule is simple and absolute:

The pre-hash of each commit must match the post-hash of its parent. If the chain breaks, the commit is rejected. No exceptions.

This gives the OIG a tamper-evident property similar to a blockchain, but without consensus overhead. The chain is validated locally and enforced at the commit boundary. If an agent produces a commit that does not match the expected graph state, it is rejected before it reaches storage.

Commit A hash_post: 3a8f
Commit B hash_pre: 3a8f
Commit C hash_pre: d4e7

Linear history is enforced by default. A commit with more than one parent is rejected unless explicitly allowed. This keeps the graph simple and auditable while still supporting branching when the domain requires it.

The change model

Each commit contains one or more changes, and each change contains one or more deltas. The hierarchy:

Change hierarchy
ObjectInstanceGraphCommit
   ObjectInstanceGraphChange[]
       Change (CREATE | UPDATE | DELETE)
           ChangeDelta[] (SCALAR_SET)

A single function call can produce multiple changes — for example, constructing a parent entity and its children in one operation. But all changes within a commit are atomic: they either all apply or none do.

Changes are typed by kind: instance mutations (class_instance_changes) and relationship mutations (class_instance_relationship_changes). This separation makes it possible to replay, audit, or project changes independently.

Provenance: every action is attributed

Every commit carries an author_id. This is not optional. When a human calls a function through the API, their identity is the author. When an AI agent calls the same function through the same typed API, the agent's identity is the author.

Commit action metadata
{
  "actor_id":        "a1b2c3d4-...",      // Who
  "operation_label": "identity.signup",  // What canonical operation
  "call_target":     "instance",         // Where in the graph
  "function_id":     "e5f6a7b8-..."       // Which function was invoked
}

This metadata is indexed separately from the commit payload, making it possible to query "what did actor X do" or "which operations touched entity Y" without deserializing every commit.

Same graph. Same commits. Human or agent — always attributed. There is no separate "agent log" or "user activity feed." The commit history is the single source of truth for what happened and who did it.

Lanes: commits scoped by projection

Commits do not exist in a flat list. They live in lanes. A lane is identified by the combination of a branch and a projection hash. This means:

  • Multiple projections (actor views) can exist on the same branch
  • Each projection tracks its own HEAD commit
  • The lane HEAD stores the latest commit ID and post-hash for resumption
Lane HEAD
{
  "commit_id":   "b2ddfd2c-492e-5a80-...",
  "graph_hash_post": "460d30b861a9e873...",
  "object_instance_graph_id": "475efb0e-4516-...",
  "v": 1
}

The lane HEAD is what allows the system to resume from any point. When a new function call arrives, the committer reads the HEAD, validates hash continuity, appends the new commit, and advances the HEAD. The process is deterministic and repeatable.

Validation: what gets enforced

The OIG commit validator enforces a strict set of rules before any commit is accepted:

  • Hash continuity — pre-hash must match parent's post-hash
  • Linear history — single parent by default; multi-parent requires opt-in
  • Root metadata — every commit must reference the root object and class config
  • UTC timestamps — all timestamps in UTC, no timezone ambiguity
  • Non-empty changes — empty commits are rejected (except seed commits)
  • Author present — every commit must have an author_id

If any rule fails, the commit is rejected with a typed validation error. The graph state does not change. This means the ledger is always consistent — there is no "partial commit" state.

The full flow: function call to committed receipt

When a human or agent calls a function on the canonical graph, this is what happens:

Actor Human / Agent
API Typed call
Handler Graph ops
Commit Validated
Lane HEAD advanced
  1. The actor calls a typed function through the canonical API
  2. The handler executes graph operations (create, update, delete)
  3. The commit builder collects all changes into a commit
  4. The validator checks hash continuity, linearity, and attribution
  5. The committer writes the commit to the lane and advances the HEAD
  6. The commit is now a permanent, attributed receipt

The same flow applies whether the actor is a human user clicking a button in the interface, an AI agent making a tool call, or a service handler executing a scheduled operation. The graph does not distinguish by origin — it distinguishes by identity.

Why this matters for AI

AI agents in Aware are not wrappers around the system. They are first-class actors on the canonical graph. When an agent calls a function, it produces the same kind of commit a human would. The provenance stream shows agent and human actions side by side, with the same level of detail and accountability.

This design solves a fundamental problem with AI systems: auditability. When something goes wrong, you can trace back through the commit chain and see exactly which actor made which change, when, and what the graph state was before and after. No black boxes. No hidden state.

Why this matters for services

The OIG commit chain is what makes the economy rails possible. Pricing, settlement, smart contracts — all of these operate over the same committed receipts. When a service processes a transaction, the commit records what happened with full provenance. When a settlement is disputed, the hash chain provides an immutable audit trail.

For service providers on the Aware network, this means trust is built into the substrate. You do not need to build your own audit system. The canonical graph already is one.

The OIG is not just a database log. It is a canonical ledger where every action — human, agent, or automated — becomes a hash-chained, attributed, validated receipt. That is the foundation of trust in the Aware ecosystem.