# gizdb:gate

who may read and write which rows of a Shape. It is the one place that applies the Policy (grants on records and the ancestry of records, db/policy.giz) to a Shape's rows, so a page, an API, an agent's tool and a background job that act through a Db with a Scope (db/data.giz) are all judged the same way, by the same function.

A stored Shape is a record of the Policy named SPACE/table/NAME, and each of its rows is SPACE/NAME/KEY below it (or below the row that its @Within field names). A grant on the table reaches every row; a grant on one row reaches that row and its children. A read adds a condition to the query, so a row the actor may not read is never selected; a field the actor may not read is selected as NULL. A write is checked before it runs, and a row is placed in the Policy in the transaction that inserts it.

```gizlang
import * as Gate from "gizdb:gate";
```

## Types

### `Scope`

```gizlang
type Scope = { space: string; actor: Security.Principal; now: i64; held: Task.Cell<Vec<Held>>; }
```

Who acts: the actor, the Space whose records they are, and the time (ms since 1970). A Scope is for one request: it remembers what the Policy
said of the actor's roles on the tables, so the reads of a page ask once. Rows change no grant on a table; `provision` forgets what it knew.

- `space`: `string`
- `actor`: `gizlang_security.Principal`
- `now`: `i64`
- `held`: `gizlang_task.Cell<Vec<M50.Held>>`

### `Access`

```gizlang
type Access = { readable: Vec<bool>; writable: Vec<bool>; role: Security.Role; mayWrite: bool; }
```

What a role may do with the fields of a Shape. A field with a @Read role is read when the role is at least it; a field with a @Write
role is written when the role is at least it and also the Shape's write role; a key and a computed field are never written.

- `readable`: `Vec<bool>`
- `writable`: `Vec<bool>`
- `role`: `gizlang_security.Role`
- `mayWrite`: `bool`

### `Masks`

```gizlang
type Masks = { conds: Vec<string>; slots: Vec<Typed.Slot>; params: Vec<Value>; }
```

The masks of the fields with a @Read role: for each field a SQL condition that is true on the rows where the actor may read it
(empty for a field that any reader sees), with its parameters numbered from `first`. A role is judged once however many fields have it.

- `conds`: `Vec<string>`
- `slots`: `Vec<M54.Slot>`
- `params`: `Vec<M55.Value>`

### `Plan`

```gizlang
type Plan = { set: Vec<bool>; writes: Vec<Policy.Write>; }
```

What a write sets: `set` flags the fields that it writes, and `writes` are the Policy statements that go in its transaction.

- `set`: `Vec<bool>`
- `writes`: `Vec<M60.Write>`

## Functions

### `scope`

```gizlang
function scope(space: string, actor: Security.Principal, now: i64): Result<Scope, string>
```

A Scope. A Space is named as a reference part is: 1 to 64 of a-z 0-9 _ . -

Effects: fail, io.

### `checked`

```gizlang
function checked(shape: Model.Shape): Result<bool, Model.Rejection>
```

Whether a Shape can be judged: stored under a table that names a Policy record, with a key of text or integers.

Effects: fail.

### `keyOf`

```gizlang
function keyOf(shape: Model.Shape, values: Vec<Value>): Result<string, Model.Rejection>
```

The key text of a row's values (the parts of a composite key are joined by /).

Effects: fail.

### `readable`

```gizlang
function readable(source: Source, s: Scope, shape: Model.Shape, first: i64): Result<Policy.Condition, Model.Rejection>
```

The condition that selects only the rows that the actor may read, with its parameters numbered from `first`.

Effects: fail, read, write, console, io.

### `access`

```gizlang
function access(source: Source, s: Scope, shape: Model.Shape, ref: Security.ResourceRef): Result<Access, Model.Rejection>
```

The access of the actor to the record `ref` (a row, or the table for a row that does not exist yet).

Effects: fail, read, write, console, io.

### `accessToTable`

```gizlang
function accessToTable(source: Source, s: Scope, shape: Model.Shape): Result<Access, Model.Rejection>
```

The access to a row that is created below the table (the row is not there yet).

Effects: fail, read, write, console, io.

### `accessToRow`

```gizlang
function accessToRow(source: Source, s: Scope, shape: Model.Shape, values: Vec<Value>): Result<Access, Model.Rejection>
```

The access to the row with these key values.

Effects: fail, read, write, console, io.

### `masks`

```gizlang
function masks(source: Source, s: Scope, shape: Model.Shape, first: i64): Result<Masks, Model.Rejection>
```

The masks of the fields of SHAPE that the actor of S may read only on some rows, with parameters numbered from FIRST
(Masks).

Effects: fail, read, write, console, io.

### `admitCreate`

```gizlang
function admitCreate(source: Source, s: Scope, shape: Model.Shape, values: Vec<Value>): Result<Plan, Model.Rejection>
```

Admit a new row: the actor holds the Shape's write role on its parent. The Plan places the row.

Effects: fail, read, write, console, io.

### `admitUpdate`

```gizlang
function admitUpdate(source: Source, s: Scope, shape: Model.Shape, old: Vec<Value>, values: Vec<Value>): Result<Plan, Model.Rejection>
```

Admit a change of the row `old` (as the actor reads it) to `values`: the actor holds the write role on the row, and on the new
parent when a @Within field moves it.

Effects: fail, read, write, console, io.

### `admitRemove`

```gizlang
function admitRemove(source: Source, s: Scope, shape: Model.Shape, old: Vec<Value>): Result<Plan, Model.Rejection>
```

Admit the removal of the row `old`: the actor holds the write role on it. The Plan removes its grants and its place.

Effects: fail, read, write, console, io.

### `provision`

```gizlang
function provision(s: Scope, shapes: Vec<Model.Shape>): Result<Vec<Policy.Write>, Model.Rejection>
```

The statements that make the Policy tables and place the table record of each Shape, with the actor as its owner. Run them once for
each Space; they can run again.

Effects: fail, read, write, console, io.

