> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cast.digitalfinancehq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Layer 0 — the architecture, enforced

> How a working demo proves the principles, with the guarantees shown in the schema itself.

The principles in this guide are not aspirational. This page shows where each one is enforced in a working build — a demo that walks one bilateral payment confirmation from a held invoice to a signed, independently verifiable record.

The snippets below are taken **verbatim** from the build's `schema.sql` and `canonicalize.ts`. Where the guide makes a structural claim, the code that backs it is shown next to it — so the claim and the constraint are the same characters on the page.

<Note>
  This is **Session 1 scope**: the bilateral event loop. It deliberately proves the foundation — that a verified, co-authored record can be created and independently checked — before any downstream ledger automation is built. See [Session 1 scope](#session-1-scope) below for exactly what is and isn't included.
</Note>

## What the demo does

One payment, three screens, each written for a different audience. The asymmetry is the point: the people doing the work never see cryptography; the people who underwrite the result see all of it.

| Screen               | Audience                    | Shows JSON / crypto?                                 |
| -------------------- | --------------------------- | ---------------------------------------------------- |
| Buyer AP queue       | Controller                  | **No** — operational queue only                      |
| Seller Trade Message | Vendor AP clerk, on a phone | **No** — amount, invoice, destination, three actions |
| Verifier view        | Lender / auditor / insurer  | **Yes** — payload JSON, hashes, signature, recompute |

The verifier screen ends with a **Recompute & verify** button that re-derives the hash and checks the signature entirely in the browser — the clearest demonstration of the thesis, because the viewer proves it themselves rather than taking our word.

<Card title="See the demo" icon="play" href="mailto:contact@digitalfinancehq.com?subject=CAST%20Layer%200%20demo%20walkthrough">
  The Layer 0 build is a working application, available on request. Reach out to book a walkthrough of the full buyer → seller → verifier flow, including the in-browser recompute.
</Card>

## Verification is a precondition to insert

The central claim of the architecture is that a record cannot exist unless it was verified first. This is not a status column that an event can sit in as "unverified" — it is the structure of the only code path that reaches the database.

The single transaction recomputes the hash, checks the signature, and only then writes both the event and its signature together. If either check fails, the transaction rolls back and **nothing is written**:

```text The gated transaction (shape, from schema.sql) theme={"dark"}
BEGIN;
  -- assert sha256(payload_version || canonical_json) == payload_hash
  -- assert ed25519.verify(payload_hash, signature, public_key)
  -- if either assertion fails -> throw -> ROLLBACK (nothing is written)
  SELECT insert_signed_event(...);   -- writes events + event_signatures
COMMIT;
```

<Note>
  The two assertions run in application code **inside the same database transaction** as the insert. The guarantee is that the only path to insertion is gated by those checks, and the event row and signature row live or die together — not that the database engine itself performs the cryptography. (Stock Postgres can't verify Ed25519 without an untrusted procedural language, and the build keeps to stock Postgres so a verifier in 2031 needs no exotic extensions.) There is no "pending" state and no "unverified" flag anywhere in the schema.
</Note>

## A posting cannot exist without a bilateral event

The strongest structural guarantee, and the easiest to verify: it is a non-nullable foreign key. A ledger entry with no co-authored event behind it cannot be inserted — the database rejects it.

```sql postings — from schema.sql theme={"dark"}
CREATE TABLE postings (
  posting_id text        PRIMARY KEY,
  event_id   text        NOT NULL REFERENCES events(event_id),   -- NON-NEGOTIABLE #2
  account    text        NOT NULL,
  amount     text        NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now()
);
```

This constraint lives in the schema, not in application code — so it holds against a bug, a migration script, a direct database write, or an engineer in 2031 who never read the application.

## Signatures are over canonical hashes, not rows

A signature made today must still verify years from now, even after the `events` table gains new columns. That only works if the exact bytes that were signed are reproducible. The build signs a hash of the *canonicalized payload*, never the database row:

```ts canonicalize.ts — the single definition of the signed bytes theme={"dark"}
export function payloadHash(payload: unknown, version: CanonVersion = 'v1'): Buffer {
  const canon = canonicalize(payload, version);
  const signedBytes = Buffer.concat([Buffer.from(version, 'utf8'), canon]);
  return createHash('sha256').update(signedBytes).digest();
}
```

The canonicalizer is committed code with a sha256 registered in the database. **The server refuses to start if the file on disk drifts from the registered hash** — so the function that produced a signature can always be reproduced exactly. The browser verifier mirrors this function byte-for-byte, pinned by a parity test.

<Card title="Lineage — why this is the asset" icon="link" href="/primitives/lineage">
  The property that makes a transaction insurable, financeable, and survivable.
</Card>

## One active policy, enforced in SQL

```sql policy_versions — from schema.sql theme={"dark"}
CREATE UNIQUE INDEX policy_versions_one_active
  ON policy_versions (active) WHERE active = true;
```

A partial unique index makes "more than one active policy" unrepresentable. The rule is in the schema, not a convention the application is trusted to follow.

## How the record stays append-only

The system **never updates and never deletes**. Every state transition appends a new event; every correction is a new event, not an edit. The buyer queue even distinguishes held from confirmed by whether a work order's `bilateral_event_id` is null yet — a value that can only ever be *set*, and only through the verified insert path.

<Note>
  This is a property of how the system operates: there is no code path that updates or deletes an event. It is described here as behavior rather than as a database-level prohibition, which is the precise and honest framing.
</Note>

## Five of the seven invariants, enforced today

The [full architecture defines seven structural invariants](/foundations/structural-invariants). This build, operating on the bilateral loop without settlement, enforces five of them — and adds two implementation-level guarantees of its own.

| Architecture invariant                              | In this build?                               |
| --------------------------------------------------- | -------------------------------------------- |
| Posting requires a Bilateral Event                  | **Enforced** — non-nullable FK shown above   |
| Lineage hash chain integrity                        | **Enforced** — recomputed at verify time     |
| Single active Policy Version                        | **Enforced** — partial unique index          |
| Hard-coded triggers cannot be suppressed            | **Enforced** — first-payment and bank-change |
| Events are append-only                              | **Enforced** — no update/delete path         |
| Bilateral Event requires confirmed Work Order state | Exercised when the full state machine lands  |
| Settlement export requires approved Control track   | Out of Session 1 scope — settlement is gated |

<Note>
  The two not yet exercised both concern **settlement**, which Session 1 deliberately gates out. They are not unenforced by oversight — the demo never reaches the stage where they apply. On top of the five, this build adds two implementation guarantees the schema-level list doesn't enumerate: **signature verification as a precondition to insert**, and **WebAuthn attestation stored on every signature**.
</Note>

## Session 1 scope

The demo proves the foundation deliberately before building on it. What that means precisely:

<CardGroup cols={2}>
  <Card title="Implemented" icon="circle-check">
    The bilateral loop: **Event**, **Policy Version**, and **Work Order** as live objects, plus the **Posting** constraint (the table exists with its non-nullable FK, enforcing the guarantee even though it is never written this session).
  </Card>

  <Card title="Scoped for later" icon="clock">
    **Case** — the exception primitive — becomes a table when exception handling is built. Postings, GL coding, budget checks, ERP export, and settlement are gated until the bilateral loop is proven at volume.
  </Card>
</CardGroup>

The gate is explicit: downstream ledger automation is out of scope until the bilateral loop runs at 1,000 events, above a 70% confirmation rate, with a median confirmation under five minutes. The `settlement_state` column is even `CHECK`-locked to a single value, so the schema itself rejects a settlement write this session.

<Note>
  Why prove the loop first: the bilateral event is the entire architectural claim. If a co-authored, independently verifiable record can be created and checked, everything downstream is a configuration problem. If it can't, no amount of downstream automation rescues it.
</Note>

## What an external reader should take away

Most of these guarantees are not promises in prose — they are constraints in a schema and a hash in a registry. A skeptical reader does not have to trust the operator; they can read the same constraints shown here, and on the verifier screen, recompute the proof themselves.

<Card title="See the five primitives these enforce" icon="cube" href="/primitives/overview">
  Event, Policy Version, Work Order, Posting, Case — the objects this build instantiates.
</Card>
