|**Implements**| a subset of `docs/spec.md` (Draft 0.1) |
7
|**Goal**| A push to a repository on OxygenHub (Earth) runs `.flow/pipeline.kdl` in Firecracker microVMs, and the hub shows the run as a graph of jobs with live status and logs. |
8
9
M0 is the smallest slice that exercises the real architecture: a typed
10
pipeline compiled to a canonical form, host-side execution in the default
11
isolation tier, receipts computed by the host, and results reported to the
12
hub as checks. Everything M0 leaves out is listed at the end.
13
14
##1. Pipeline subset
15
16
The file is `.flow/pipeline.kdl` in the state being built (KDL 2.0). M0
17
accepts:
18
19
```kdl
20
schema-version 1
21
22
sandbox "alpine" {
23
runtime "microvm" // "microvm" (default) | "syscall"; "wasm" is refused in M0
24
rootfs "cas://blob/<64 hex>" // BLAKE3 of an ext4 image the runner holds
25
memory-limit "1GiB" // KiB, MiB, GiB
26
cpu-limit 2
27
network "isolated" // M0 accepts only "isolated"
28
}
29
30
job "lint" {
31
sandbox "alpine"
32
scope "src/**" "README.md" // recorded; the job runs on every push in M0
33
env { LANG "C.UTF-8" }
34
exec "grep" "-rn" "TODO" "src"
35
}
36
37
job "test" {
38
sandbox "alpine"
39
depends-on "lint"
40
exec "sh" "-eu" "test.sh"
41
}
42
```
43
44
Rules, all checked by `flow check` and again by the hub before anything
45
runs (spec §2.2 I2, §3.2):
46
47
-Unknown nodes, arguments or properties are errors, with the line.
48
- Every string stays a string; `cpu-limit` is an integer from 1 to 16;
49
`memory-limit` parses to 64 MiB to 16 GiB.
50
- A job names a declared sandbox, has a non-empty `exec` of literal
51
strings, and `depends-on` only declared jobs; the graph has no cycle.
52
- Names are 1 to 64 characters from `[A-Za-z0-9._-]`.
53
-`exec` becomes `argv` unchanged: metacharacters are bytes (spec §10.1).
54
A job that wants a shell names one, as `sh` above; nothing adds one.
-**Token:** a hub administrator creates a one-time registration token on Admin → Runners.
133
-**Registering:**`flow runner register https://hub --token … [--name N] [--ca PATH] [--label L]…` sends the runner's signing identity, architecture, OS, version and labels (`POST /api/v1/flow/runners/register`). It gets back the runner's own credential and writes hub, credential, name, CA and labels to `runner.toml` (owner-only). That file stands in for a `[runner]` section `flow.toml` lacks, and `flow runner` then starts from it.
134
-**Key:** registration binds the key; the hub accepts receipts from that runner signed by no other.
135
-**Claims:** every claim carries the runner's description (`info`: architecture, OS, version, labels, capacity) for the Runners page.
136
-**Old configuration:** runners configured with a `hub.toml` token still work. Their key is bound on their first signed receipt.