~/bend-docscommunity

arc.bend checks

raw source on the hub · import 0x9a0c458f159a102b8f9b9e65b34d7d79/arc.bend as Arc

1 import
import Base

Types

type NodeRole source · line 13 · raw

Data

---- vocabulary ---- UserDevice: a user's own device. Server: a machine the project runs. Overlay: the private (overlay) network between them. Outside: someone else's servers.

type PhysicalDevice source · line 19 · raw

Data

type Vendor source · line 22 · raw

Data

type Org source · line 25 · raw

Data

type Person source · line 31 · raw

Data

The agreement between the organization and its people: who they are (identities in the org's directory domain), what each is granted per scope (actions; none means no access), and budgets. It describes the people who work on the system, not the system; the diagram may omit it.

type Grant source · line 33 · raw

Data

type Budget source · line 35 · raw

Data

type Agreement source · line 37 · raw

Data

type Host source · line 39 · raw

Data

type Node source · line 44 · raw

Data

type ContainerKind source · line 54 · raw

Data

What a container is. The list is closed: something that is none of these is not a container. Client: the app, on the user's device. The private overlay is a node, not a container. DataApi: answers queries on records and changes them. Harness: an agent harness, the loop around a model (tools, context, threads), driven over its remote-control API. Proxy: forwards connections to another container, adding what it lacks, such as TLS or authentication. ModelApi: answers model calls. Cli: a command a person runs. Worker: has no API of its own; it only moves data between data APIs, so it is the first thing to fold into a data API's own actions.

type Owner source · line 64 · raw

Data

Whether the project builds and runs it, or uses it as it is.

type Exposure source · line 69 · raw

Data

Who can reach it: its own machine (127.0.0.1), the local network, the overlay, the device it is on, anyone.

type Cap source · line 79 · raw

Data

What a container provides. Hosting is serving the app itself (its HTML and scripts); a data API may also host the app only while it is private (shared_hosting_ok). Observability is receiving a running container's errors, traces and structured logs.

type Lang source · line 86 · raw

Data

type Container source · line 95 · raw

Data

type Part source · line 98 · raw

Data

type System source · line 105 · raw

Data

Definitions

def org source · line 109 · raw

@s:System -> Org

---- access ----

def nodes source · line 114 · raw

@s:System -> List<&2, Node>

def containers source · line 119 · raw

@s:System -> List<&2, Container>

def parts source · line 124 · raw

@s:System -> List<&2, Part>

def nkey source · line 134 · raw

@n:Node -> String

def ckey source · line 139 · raw

@c:Container -> String

def con source · line 144 · raw

@c:Container -> String

def caps source · line 149 · raw

@c:Container -> List<&2, Cap>

def pkey source · line 154 · raw

@p:Part -> String

def pin source · line 159 · raw

@p:Part -> String

def pon source · line 164 · raw

@p:Part -> String

def nkeys source · line 169 · raw

@xs:List<&2, Node> -> List<&2, String>

def ckeys source · line 176 · raw

@xs:List<&2, Container> -> List<&2, String>

def pkeys source · line 183 · raw

@xs:List<&2, Part> -> List<&2, String>

def keys source · line 191 · raw

@+s:System -> List<&2, String>

Keys links may name: containers and parts.

def is_server source · line 195 · raw

@r:NodeRole -> Bool

---- predicates on the vocabulary ----

def is_outside source · line 202 · raw

@r:NodeRole -> Bool

def is_device source · line 209 · raw

@r:NodeRole -> Bool

def is_overlay source · line 216 · raw

@r:NodeRole -> Bool

def one_if source · line 223 · raw

@b:Bool -> Nat

def overlay_nodes.go source · line 230 · raw

@xs:List<&2, Node> -> Nat

def overlay_nodes source · line 240 · raw

@+s:System -> Nat

Private access is represented by exactly one Overlay node.

def is_client source · line 243 · raw

@k:ContainerKind -> Bool

def is_data_api source · line 250 · raw

@k:ContainerKind -> Bool

def is_ours source · line 257 · raw

@o:Owner -> Bool

def is_local source · line 264 · raw

@e:Exposure -> Bool

def is_tailnet source · line 271 · raw

@e:Exposure -> Bool

def is_rust source · line 278 · raw

@l:Lang -> Bool

def str_eq source · line 286 · raw

@a:String -> @b:String -> Bool

---- keys, like foreign keys ----

def has source · line 289 · raw

@+s:String -> @xs:List<&2, String> -> Bool

def owned_device source · line 296 · raw

@+key:String -> @+name:String -> @xs:List<&2, PhysicalDevice> -> Bool

def host_in_inventory source · line 303 · raw

@h:Host -> @name:String -> @o:Org -> Bool

def node_owned source · line 312 · raw

@n:Node -> @+o:Org -> Bool

def owned_nodes.go source · line 317 · raw

@xs:List<&2, Node> -> @+o:Org -> Bool

def owned_nodes source · line 325 · raw

@+s:System -> Bool

Every server and user device is in the owner's inventory or on its vendor's cloud.

def pick_str source · line 328 · raw

@c:Bool -> @a:String -> @b:String -> String

def distinct_keys source · line 336 · raw

@xs:List<&2, String> -> Bool

No key names two things.

def all_in source · line 344 · raw

@xs:List<&2, String> -> @+ks:List<&2, String> -> Bool

Every key in xs names something in ks.

def part_ins source · line 351 · raw

@xs:List<&2, Part> -> List<&2, String>

def part_ons source · line 358 · raw

@xs:List<&2, Part> -> List<&2, String>

def container_ons source · line 365 · raw

@xs:List<&2, Container> -> List<&2, String>

def well_formed source · line 383 · raw

@+s:System -> Bool

The system is well formed: node keys and container/part keys are unique, every container is on a node, every part in a container, and every link joins two things that exist.

def part_home source · line 391 · raw

@+k:String -> @xs:List<&2, Part> -> String

---- looking things up ----

def home source · line 399 · raw

@+k:String -> @+s:System -> String

The container a key belongs to: itself, or the one its part sits in.

def none source · line 402 · raw

Container

def pick_c source · line 405 · raw

@hit:Bool -> @c:Container -> @other:Container -> Container

def container source · line 413 · raw

@+k:String -> @xs:List<&2, Container> -> Container

The container with key k (an empty one when k is unknown; well_formed rules that out).

def pick_r source · line 420 · raw

@hit:Bool -> @r:NodeRole -> @other:NodeRole -> NodeRole

def node_role source · line 427 · raw

@+k:String -> @xs:List<&2, Node> -> NodeRole

def part_node source · line 436 · raw

@+k:String -> @xs:List<&2, Part> -> String

def node_of source · line 444 · raw

@+k:String -> @+s:System -> String

The node a container or part runs on, and its role.

def role_of source · line 447 · raw

@+k:String -> @+s:System -> NodeRole

def container_exposure source · line 450 · raw

@c:Container -> Exposure

def exposure_of source · line 455 · raw

@+k:String -> @+s:System -> Exposure

def private_ok source · line 460 · raw

@c:Container -> @+ns:List<&2, Node> -> Bool

---- where it runs ---- On a server, everything is reachable only from the server itself or over the overlay.

def all_private source · line 465 · raw

@xs:List<&2, Container> -> @+ns:List<&2, Node> -> Bool

def servers_private source · line 472 · raw

@+s:System -> Bool

def devices_via_network.go source · line 476 · raw

@xs:List<&2, Link> -> @+s:System -> Bool

A device reaches a server over the overlay only when the destination is exposed to the tailnet.

def devices_via_network source · line 486 · raw

@+s:System -> Bool

def device_reaches source · line 490 · raw

@+key:String -> @xs:List<&2, Link> -> @+s:System -> Bool

A server container needs overlay exposure exactly when a device-origin link reaches it.

def exposure_for_reach source · line 497 · raw

@c:Container -> @reached:Bool -> Bool

def exposure_follows_reach.go source · line 502 · raw

@xs:List<&2, Container> -> @+s:System -> Bool

def exposure_follows_reach source · line 511 · raw

@+s:System -> Bool

def is_cap source · line 515 · raw

@want:Cap -> @c:Cap -> Bool

---- what it is: minimality, every capability provided exactly once ----

def count_in source · line 530 · raw

@+want:Cap -> @cs:List<&2, Cap> -> Nat

def direct source · line 537 · raw

@+want:Cap -> @xs:List<&2, Container> -> Nat

def tailnet_hosting.go source · line 544 · raw

@xs:List<&2, Container> -> Nat

def tailnet_hosting source · line 554 · raw

@+s:System -> Nat

How many containers host the app at Tailnet exposure.

def provided source · line 558 · raw

@want:Cap -> @+s:System -> Nat

How many containers provide want. One tailnet host plus one overlay composes private hosting.

def cons_if source · line 566 · raw

@b:Bool -> @k:String -> @xs:List<&2, String> -> List<&2, String>

---- observability: everything we run reports to the observability provider ----

def providers source · line 574 · raw

@+want:Cap -> @xs:List<&2, Container> -> List<&2, String>

Keys of the containers that provide want.

def part_container source · line 582 · raw

@ps:List<&2, Part> -> @+k:String -> String

The container a link end belongs to: a part's container, else the key itself.

def reports_to source · line 590 · raw

@ls:List<&2, Link> -> @+k:String -> @+ps:List<&2, Part> -> @+obs:List<&2, String> -> Bool

Some link from container k (or one of its parts) reaches one of obs.

def observed.go source · line 597 · raw

@xs:List<&2, Container> -> @+s:System -> @+obs:List<&2, String> -> Bool

def observed source · line 607 · raw

@+s:System -> Bool

Every container we build (ours, with source) links to a container providing Observability.

def tailnet_data_apis.go source · line 610 · raw

@xs:List<&2, Container> -> Nat

def tailnet_data_apis source · line 620 · raw

@+s:System -> Nat

The data APIs the overlay reaches: the client's data API. Local and outside ones are its sources.

def own_data_apis.go source · line 623 · raw

@xs:List<&2, Container> -> @+ns:List<&2, Node> -> Nat

def own_data_apis source · line 633 · raw

@+s:System -> Nat

The system's own data APIs: those not on someone else's servers. "Exactly one" means one store.

def shared_hosting_ok source · line 637 · raw

@c:Container -> Bool

A data API may also host the app only while it is private.

def shared_hosting_private.go source · line 642 · raw

@xs:List<&2, Container> -> Bool

def shared_hosting_private source · line 649 · raw

@+s:System -> Bool

def backend source · line 653 · raw

@c:Container -> Bool

---- a goal: every part of our own non-client containers is Rust ----

def rust_ok source · line 658 · raw

@p:Part -> @+s:System -> Bool

def all_rust.go source · line 663 · raw

@xs:List<&2, Part> -> @+s:System -> Bool

def all_rust source · line 670 · raw

@+s:System -> Bool

def container_ours source · line 674 · raw

@c:Container -> Bool

Every modeled part belongs to a container we build; someone else's program is a black box.

def parts_ours.go source · line 679 · raw

@xs:List<&2, Part> -> @+s:System -> Bool

def parts_ours source · line 686 · raw

@+s:System -> Bool

def path source · line 690 · raw

@+k:String -> @+s:System -> String

---- the diagram (D2): nodes as boxes, containers inside their node, parts inside their container ----

def node_box source · line 693 · raw

@n:Node -> String

def node_boxes source · line 702 · raw

@xs:List<&2, Node> -> String

def stack_label source · line 709 · raw

@frameworks:List<&2, String> -> @libraries:List<&2, String> -> String

def container_box source · line 724 · raw

@c:Container -> String

def container_boxes source · line 729 · raw

@xs:List<&2, Container> -> String

def part_box source · line 736 · raw

@p:Part -> @+s:System -> String

def part_boxes source · line 741 · raw

@xs:List<&2, Part> -> @+s:System -> String

def style source · line 748 · raw

@live:Bool -> String

def edges source · line 755 · raw

@xs:List<&2, Link> -> @+s:System -> String

def d2 source · line 764 · raw

@+s:System -> String

def ends_with_at source · line 776 · raw

@+identity:String -> @+domain:String -> Bool

---- the agreement: people, their identities and grants ----

def people_in.go source · line 779 · raw

@xs:List<&2, Person> -> @+domain:String -> Bool

def people_in_domain source · line 787 · raw

@a:Agreement -> Bool

Every person's identity is in the organization's directory domain.

def is_identity source · line 792 · raw

@+id:String -> @xs:List<&2, Person> -> Bool

def identities_known.go source · line 799 · raw

@ids:List<&2, String> -> @+xs:List<&2, Person> -> Bool

def identities_known source · line 807 · raw

@ids:List<&2, String> -> @a:Agreement -> Bool

Every identity actually in use (from a snapshot) is one of the agreement's people.

def pick_list source · line 812 · raw

@c:Bool -> @a:List<&2, String> -> @b:List<&2, String> -> List<&2, String>

def granted.go source · line 819 · raw

@xs:List<&2, Grant> -> @+person:String -> @+scope:String -> List<&2, String>

def granted source · line 827 · raw

@a:Agreement -> @+person:String -> @+scope:String -> List<&2, String>

What person is granted on scope; [] when nothing is granted there.