OXYGENHUB

The specification, renamed from Xenon to OxygenFlow (.flow/pipeline.kdl, flow/provenance/v1, flow-casfs), and a README a083cc802892

Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-28 12:10 UTC
Signature
✔ signed by Andy McCall
Hash
a083cc802892c7b532f19bd852a5f82a32d283719fada2c46c050bd4fac3c090
Depends on
e0918b887850
Depended on by
8aa45fa6ece5 4dd392d16454 494a1b9a8ac2 731413202557 85275e1ef3b7 f201e1bc5bcd 1b160d372d9e 06a4c472b385 28cc603f737d 4be5e4cd0af6 077a65242359 da5118d25db2 2594278f49b2 cd03b9844516 35f7a849bcc5 e87c1c138187 2be1fe4ad345 f4e51e63582d e20897216221 46fe2c815cc3 ea81796bb757 1e6b9fb1e73f 0077c7488e5d de1d7926185f 82cf6e91d398 89171fca079c d60aac6c3f8a 62829d15ef09 6d53fb7d00ec 9a6fac2b40a9 630ee66034b2 1a1793bdfcc0 1abadd4a2fa6 fd2d4822f7f3 bf7bb1b80fa3 02b127d2c721 e576e08617dc 701dcbc5d468 b647ab72d51e a72abeeedd78 bb643c252515 fe128fa67a06 fc10d9e80383 c140d0d8bc9c
In bookmarks
main newer-pipeline push-uses-login
In tags
v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.5.0 v0.5.1 v0.5.2 v0.5.3
Edits
2 atoms, 2 tree operations, 2 files

Browse the tree at this change

added README.md +106 −0
1 +
# OxygenFlow
2 +
3 +
Hermetic pipelines for Oxygen repositories:
4 +
5 +
- a typed pipeline in `.flow/pipeline.kdl`
6 +
- jobs run in isolation tiers, Firecracker microVMs by default
7 +
- the host writes the receipts
8 +
- results go to OxygenHub as checks and appear on its Flow tab
9 +
10 +
The specification is [docs/spec.md](docs/spec.md). What works today is
11 +
[docs/m0.md](docs/m0.md).
12 +
13 +
## A pipeline
14 +
15 +
```kdl
16 +
schema-version 1
17 +
18 +
sandbox "alpine" {
19 +
    runtime "microvm"
20 +
    rootfs "cas://blob/…"      // printed by `flow rootfs import`
21 +
    memory-limit "256MiB"
22 +
    network "isolated"
23 +
}
24 +
25 +
job "build" {
26 +
    sandbox "alpine"
27 +
    exec "make"
28 +
}
29 +
30 +
job "test" {
31 +
    sandbox "alpine"
32 +
    depends-on "build"
33 +
    exec "sh" "-eu" "test.sh"   // argv, run as written: no shell unless you name one
34 +
}
35 +
```
36 +
37 +
Each job boots its own microVM:
38 +
39 +
- it has no network device
40 +
- the rootfs is read-only
41 +
- the workspace is the state being built, read-write at `/src`
42 +
- the job runs as a user that is not root
43 +
44 +
This repository's own pipeline is [.flow/pipeline.kdl](.flow/pipeline.kdl).
45 +
46 +
## Commands
47 +
48 +
    flow check                 # validate .flow/pipeline.kdl, print jobs and the pipeline hash
49 +
    flow run [JOB…]            # run the pipeline on this directory, locally, in microVMs
50 +
    flow rootfs import T.tgz --sha256 HEX   # make a rootfs image; prints the `rootfs` line to pin
51 +
    flow rootfs list
52 +
    flow hash FILE             # BLAKE3, for pinning in flow.toml
53 +
    flow runner                # claim and run jobs for the hub in flow.toml
54 +
55 +
## A Flow home
56 +
57 +
`$FLOW_HOME` (default `~/.local/share/flow`) holds:
58 +
59 +
- `flow.toml`
60 +
- the pinned Firecracker binary, guest kernel and `flow-init`
61 +
- rootfs images under `cas/`
62 +
- scratch space
63 +
64 +
Every pinned file is checked against its BLAKE3 before use.
65 +
66 +
```toml
67 +
[microvm]
68 +
firecracker = { path = "bin/firecracker", blake3 = "…" }
69 +
kernel = { path = "kernel/vmlinux", blake3 = "…" }
70 +
init = { path = "bin/flow-init", blake3 = "…" }
71 +
72 +
[runner]                     # only for `flow runner`
73 +
hub = "https://hub.example:7343"
74 +
token = "…"                  # listed in the hub's [flow] runner_tokens
75 +
ca = "/path/to/hub-ca.pem"   # when the hub's certificate is self-signed
76 +
name = "runner-1"
77 +
```
78 +
79 +
Setting one up needs Linux x86-64 with KVM and e2fsprogs 1.43 or later:
80 +
81 +
1. Build `flow` with `cargo build --release -p flow`. Build the guest init
82 +
   as a static binary:
83 +
   `RUSTFLAGS="-C target-feature=+crt-static" cargo build --release -p flow-init --target x86_64-unknown-linux-gnu`.
84 +
2. Download Firecracker v1.17.0 from its GitHub release, and check the
85 +
   published SHA-256. Download the guest kernel
86 +
   `firecracker-ci/v1.15/x86_64/vmlinux-6.1.155` from Firecracker's CI
87 +
   bucket.
88 +
3. Run `flow rootfs import alpine-minirootfs-3.24.2-x86_64.tar.gz --sha256 …`.
89 +
4. Write `flow.toml`, pinning each file by its `flow hash`.
90 +
91 +
On OxygenHub, `hub.toml` lists the runner token and the repositories whose
92 +
pushes run pipelines:
93 +
94 +
```toml
95 +
[flow]
96 +
runner_tokens = ["…"]
97 +
repos = ["owner/*"]
98 +
```
99 +
100 +
## Tests
101 +
102 +
`cargo test --workspace` runs every test that needs no VM. The microVM
103 +
conformance test also runs when `FLOW_TEST_HOME` names a Flow home and
104 +
`FLOW_TEST_ROOTFS` is the hash of an Alpine rootfs in it. The test checks
105 +
literal argv, network isolation, the read-only rootfs, and that dependents
106 +
are skipped after a failure.
added docs/spec.md +406 −0
1 +
# OxygenFlow (flow) — Deterministic Execution & Provenance Pipeline Specification
2 +
3 +
| | |
4 +
|---|---|
5 +
| **Format version** | 1 |
6 +
| **Date** | 2026-09-28 |
7 +
| **Status** | Draft 0.1 |
8 +
| **Target VCS** | Oxygen (oxy) Draft 0.8i |
9 +
| **Audience** | Implementers, Security Architects, and Systems Engineers |
10 +
11 +
12 +
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be
13 +
interpreted as described in RFC 2119.
14 +
15 +
## 1. Overview and Core Invariants
16 +
17 +
OxygenFlow (flow) is a content-addressed, hermetic execution engine, runner system,
18 +
and pipeline language designed natively for the Oxygen (oxy) version control
19 +
system.
20 +
21 +
Existing runner engines (GitHub Actions, GitLab CI, Forgejo Runner) suffer from
22 +
structural flaws:
23 +
1. Workspace Bloat: Full clones, index unpacks, and checkout scans dominate I/O.
24 +
2. String Injection: Shell interpolation within untyped YAML files produces
25 +
   expression injection and command execution exploits.
26 +
3. Decoupled Supply Chain: Attestations (SLSA, in-toto, Cosign) exist outside
27 +
   the VCS, relying on external registries rather than native repository trust.
28 +
4. Coarse Caching: Opaque tarballs keyed by arbitrary string hashes fail to
29 +
   leverage commutative history or granular dependency graphs.
30 +
31 +
OxygenFlow solves these liabilities through direct integration with Oxygen:
32 +
- Zero-Copy Workspaces: Jobs mount workspaces directly from Oxygen's FastCDC-
33 +
  chunked, BLAKE3-addressed Content-Addressable Store (CAS) using Copy-on-Write
34 +
  (COW) overlays.
35 +
- Commutative History & Impact Trees: Pipelines evaluate over change closures
36 +
  rather than linear snapshot sequences. Commuting changes automatically reuse
37 +
  cached execution receipts without redundant re-execution.
38 +
- Micro-Engine Sandboxing: Jobs run inside isolated environments (WASM, gVisor,
39 +
  or MicroVMs) with strict, deny-by-default capabilities and no ambient
40 +
  network egress.
41 +
- Native Cryptographic Provenance: Provenance and execution receipts are
42 +
  generated outside the untrusted guest, encoded as deterministic CBOR, and
43 +
  signed using composite Ed25519 + ML-DSA-65 keys as native Oxygen Attest
44 +
  objects governed by in-repository Policy rules.
45 +
46 +
## 2. Threat Model and Security Architecture
47 +
48 +
### 2.1 Adversaries
49 +
- Untrusted Proposal Author: Submits code to an open repository containing
50 +
  malicious build configurations intended to escape the runner, exfiltrate
51 +
  secrets, or corrupt shared worker caches.
52 +
- Malicious Dependency / Upstream: Third-party dependencies invoked during
53 +
  build time attempting out-of-band network calls or host file modification.
54 +
- Compromised Runner / Malicious Worker: An execution node attempting to
55 +
  forge successful build receipts or inject backdoors into published artifacts.
56 +
57 +
### 2.2 Security Invariants
58 +
- I1 Deny-by-Default Execution: Sandboxes possess no network interfaces
59 +
  (excluding loopback when requested) and no host filesystem access unless
60 +
  explicitly granted in policy-signed configuration.
61 +
- I2 Injection-Free Invocation: Configuration parsing directly yields an argv
62 +
  string vector executed via execve(). Shell interpretation (/bin/sh -c) does
63 +
  not exist.
64 +
- I3 Host-Enforced Provenance: The running payload cannot author, inspect, or
65 +
  alter its own provenance statement. Provenance is emitted solely by the
66 +
  isolation hypervisor boundary.
67 +
- I4 Cryptographic Identity & Authorization: Runners execute using an Oxygen
68 +
  Identity whose KeyId is enrolled as a delegate in the repository's Policy.
69 +
  Unenrolled runners cannot publish recognized attestations or advance gates.
70 +
71 +
## 3. The OxygenFlow Configuration Language (.flow)
72 +
73 +
Pipelines are declared in KDL syntax within .flow/pipeline.kdl at the
74 +
repository root. KDL provides strict typing, structured nesting, and rejects
75 +
arbitrary text macro expansion.
76 +
77 +
### 3.1 Pipeline Specification Schema
78 +
79 +
```kdl
80 +
schema-version 1
81 +
82 +
// Define the hermetic execution boundary
83 +
sandbox "rust-builder" {
84 +
    runtime "microvm"       // Options: "wasm" | "gvisor" | "microvm"
85 +
    rootfs "cas://blob/9b5c2a1e8f3d4e7a6b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a"
86 +
    memory-limit "4GiB"
87 +
    cpu-limit 4
88 +
    network "isolated"      // Options: "isolated" | "loopback" | "egress"
89 +
}
90 +
91 +
// Job evaluated based on Oxygen change closure
92 +
job "compile-core" {
93 +
    sandbox "rust-builder"
94 +
95 +
    // Commutation boundary: runs only if change closure touches these paths
96 +
    scope "crates/oxy-core/**" "crates/oxy-server/**" "Cargo.*"
97 +
98 +
    // Zero-copy workspace mount backed by Oxygen CAS
99 +
    mount {
100 +
        source "oxy://workspace"
101 +
        target "/src"
102 +
        include "crates/oxy-core" "crates/oxy-server" "Cargo.toml" "Cargo.lock"
103 +
        readonly #true
104 +
    }
105 +
106 +
    // Ephemeral scratch space
107 +
    mount {
108 +
        source "ephemeral://tmpfs"
109 +
        target "/src/target"
110 +
        size "8GiB"
111 +
    }
112 +
113 +
    env {
114 +
        RUSTFLAGS "-Dwarnings"
115 +
        CARGO_INCREMENTAL "0"
116 +
    }
117 +
118 +
    // Direct argv execution vector (no subshell)
119 +
    exec "cargo" "build" "--release" "--package" "oxy-core"
120 +
121 +
    output {
122 +
        artifact "oxy-core-lib" {
123 +
            path "/src/target/release/liboxy_core.rlib"
124 +
            format "blob"
125 +
        }
126 +
    }
127 +
}
128 +
129 +
job "unit-tests" {
130 +
    sandbox "rust-builder"
131 +
    depends-on "compile-core"
132 +
133 +
    mount {
134 +
        source "oxy://workspace"
135 +
        target "/src"
136 +
        readonly #true
137 +
    }
138 +
139 +
    mount {
140 +
        source "artifact://compile-core/oxy-core-lib"
141 +
        target "/src/target/release/liboxy_core.rlib"
142 +
    }
143 +
144 +
    exec "cargo" "test" "--release" "--package" "oxy-core"
145 +
}
146 +
147 +
publish "release-provenance" {
148 +
    depends-on "unit-tests"
149 +
150 +
    attest {
151 +
        kind "provenance"
152 +
        bind-ref "bookmarks/main"
153 +
        include-artifacts "compile-core/oxy-core-lib"
154 +
    }
155 +
}
156 +
157 +
158 +
### 3.2 Canonical Compilation
159 +
Upon commit, .flow/pipeline.kdl is validated and compiled into a deterministic
160 +
CBOR job-graph blob. Runners evaluate the canonical CBOR to prevent syntax or
161 +
parser ambiguities across varying client platforms.
162 +
163 +
## 4. Sandbox Execution Engine
164 +
165 +
OxygenFlow implements three distinct isolation tiers depending on the workload:
166 +
167 +
### 4.1 Level 0: WASM Component Sandbox
168 +
- Intended for static linters, formatters, doc generators, and policy checks.
169 +
- Runs on a standard WebAssembly System Interface (WASI) runtime.
170 +
- Startup latency: < 5 ms.
171 +
- Zero host I/O; virtualized file system presented in-memory.
172 +
173 +
### 4.2 Level 1: Intercepted Syscall Isolation (gVisor / Landlock + seccomp-bpf)
174 +
- Intended for standard compilation and hermetic test suites.
175 +
- Emulates or filters Linux system call interfaces in user space.
176 +
- Blocks access to raw network sockets, real-time hardware clocks, and device
177 +
  nodes.
178 +
- Memory and execution CPU quotas are strictly bounded via cgroups v2.
179 +
180 +
### 4.3 Level 2: MicroVM Isolation (Firecracker / Cloud-Hypervisor)
181 +
- Intended for kernel tests, multi-container integration, and untrusted code.
182 +
- Ephemeral Linux microVM booting in < 80 ms.
183 +
- The root filesystem is presented as a read-only virtio-block device mapped
184 +
  directly to FastCDC chunks stored in Oxygen's CAS.
185 +
- Guest VM memory is cleared upon termination.
186 +
187 +
## 5. Content-Addressable Storage (CAS) & Zero-Copy Mounting
188 +
189 +
OxygenFlow runners bypass traditional clone operations. Repositories are accessed
190 +
directly via the local object store (.oxy/objects/) or streamed on demand
191 +
using Oxygen's wire protocol.
192 +
193 +
### 5.1 FUSE Overlay Mounting (flow-casfs)
194 +
1. The runner receives a task targeting an Oxygen State ObjectRef (a sorted
195 +
   list of maximal heads).
196 +
2. The nearest Checkpoint is resolved. Uncommitted changes between the
197 +
   checkpoint and heads are replayed into a virtual tree in-memory.
198 +
3. The virtual tree is exposed to the sandbox via flow-casfs:
199 +
   - File reads resolve chunks using the FastCDC gear table (32 KiB to 256 KiB,
200 +
     mean 64 KiB) pinned in Oxygen Spec Section 13.2.
201 +
   - Missing chunks are fetched lazily using the POST /objects protocol.
202 +
   - To prevent FUSE context-switch bottlenecks on many small reads, flow-casfs aggressively mmaps chunk data and utilizes host page caching.
203 +
   - All guest mutations are diverted to a scratch tmpfs layer; base objects
204 +
     remain immutable.
205 +
206 +
### 5.2 Artifact Capture
207 +
1. At task completion, flow-casfs scans the paths declared in the output block.
208 +
2. Modified outputs are chunked with FastCDC, hashed via BLAKE3-256, and
209 +
   written as canonical Blob and Chunk objects.
210 +
3. Output ObjectRefs are stored directly in the Oxygen repository.
211 +
212 +
## 6. Commutative Execution & Change Caching
213 +
214 +
In Oxygen, changes that do not share scopes (referenced atoms, placements, or
215 +
nodes) commute. OxygenFlow exploits this invariant to provide granular caching.
216 +
217 +
### 6.1 Execution Receipt Object
218 +
Every successful or failed job run emits an immutable Receipt:
219 +
220 +
```cbor
221 +
Receipt {
222 +
  version        [0]: 1
223 +
  job_name       [1]: text
224 +
  pipeline_hash  [2]: ObjectRef
225 +
  scope_tree_hash [3]: ObjectRef     // BLAKE3 tree hash of the materialized scope
226 +
  inputs         [4]: [ObjectRef]   // Artifacts and input files consumed
227 +
  environment    [5]: ObjectRef     // Hash of rootfs, compiler flags, and argv
228 +
  outputs        [6]: [ObjectRef]   // Produced artifact blobs
229 +
  exit_code      [7]: u32
230 +
  duration_ms    [8]: u64
231 +
}
232 +
```
233 +
234 +
A Receipt is hashed as an Oxygen object with type name "receipt":
235 +
ObjectRef = BLAKE3-256("oxy1 receipt " || decimal(len) || 0x00 || body)
236 +
237 +
### 6.2 Cache Re-use Invariant
238 +
Let Scope(J) be the file paths and tree nodes declared by job J.
239 +
Because changes that do not share scopes commute, we do not need to track lists of ChangeHashes. Instead, we hash the materialized tree of Scope(J).
240 +
241 +
If an existing Receipt R exists such that:
242 +
  R.job_name == J.name &&
243 +
  R.pipeline_hash == Hash(J) &&
244 +
  R.scope_tree_hash == TreeHash(Scope(J)) &&
245 +
  R.environment == CurrentEnvironmentHash
246 +
247 +
Then the job execution is bypassed. R.outputs are mapped into downstream
248 +
dependents immediately as a cached-commuted hit.
249 +
250 +
## 7. Native Provenance Specification
251 +
252 +
OxygenFlow formalizes build provenance as a native, tamper-evident Oxygen Attest
253 +
object (kind: "attest"). Provenance is generated exclusively by the runner
254 +
hypervisor, not the guest payload.
255 +
256 +
### 7.1 Provenance Object Schema
257 +
258 +
```json
259 +
Attest {
260 +
  version [0]: 1
261 +
  kind    [1]: "attest"
262 +
  repo    [2]: bytes(16)               // Oxygen Repository ID
263 +
  hlc     [3]: HLC                     // Hybrid Logical Clock
264 +
  body    [4]: {
265 +
    "type": "flow/provenance/v1",
266 +
    
267 +
    // Subject artifacts produced by the build
268 +
    "subjects": [
269 +
      {
270 +
        "name": text,
271 +
        "ref": ObjectRef,              // BLAKE3 hash of output blob
272 +
        "media_type": text
273 +
      }
274 +
    ],
275 +
276 +
    // Builder platform and execution identity
277 +
    "builder": {
278 +
      "runner_id": KeyId,              // ObjectRef of runner's Oxygen Identity
279 +
      "isolation_level": text,         // "wasm" | "gvisor" | "microvm"
280 +
      "hypervisor_image": ObjectRef    // Rootfs blob digest
281 +
    },
282 +
283 +
    // Exact input materials
284 +
    "materials": {
285 +
      "state_heads": [ChangeHash],     // Oxygen heads of the state built
286 +
      "scope_tree_hash": ObjectRef,        // Captures exact state without O(N) array bloat
287 +
      "inputs": [
288 +
        {
289 +
          "name": text,
290 +
          "ref": ObjectRef             // Content hash of locked dependencies
291 +
        }
292 +
      ]
293 +
    },
294 +
295 +
    // Structured execution arguments
296 +
    "invocation": {
297 +
      "job": text,
298 +
      "pipeline_spec": ObjectRef,      // ObjectRef of .flow/pipeline.kdl
299 +
      "argv": [text],                  // Unmodified execution vector
300 +
      "env": map<text, text>           // Explicitly whitelisted environment
301 +
    },
302 +
303 +
    // Environment observations
304 +
    "metadata": {
305 +
      "started_on": u64,               // Wallclock milliseconds
306 +
      "finished_on": u64,
307 +
      "hermetic": bool,                // Verified zero outbound network access
308 +
      "reproducible": bool
309 +
    }
310 +
  }
311 +
}
312 +
```
313 +
314 +
### 7.2 Composite Signatures
315 +
All provenance attestations are signed using Oxygen's composite signature
316 +
construction (Ed25519 and ML-DSA-65):
317 +
318 +
```cbor
319 +
Signature {
320 +
  key [0]: KeyId
321 +
  alg [1]: 1                           // 1 = Ed25519 + ML-DSA-65
322 +
  ed  [2]: bytes(64)                   // Classical signature
323 +
  ml  [3]: bytes(3309)                 // Post-quantum signature
324 +
}
325 +
```
326 +
327 +
Both signatures are computed over:
328 +
  "oxy1 sig attest\0" || KeyId || ObjectRef
329 +
330 +
## 8. Policy Integration & Bookmark Gates
331 +
332 +
Oxygen repositories enforce branch and bookmark protections via signed Policy
333 +
objects (Oxygen Spec Section 14.5). OxygenFlow integrates provenance directly into
334 +
policy evaluation during push validation.
335 +
336 +
### 8.1 Policy Gate Definition
337 +
A Policy rule governing a bookmark MAY demand valid OxygenFlow attestations. To mitigate a compromised authorized worker, high-security repositories can require **Consensus Builds** by setting the threshold > 1. This requires multiple independent runner identities to arrive at the exact same output hashes and both sign it.
338 +
339 +
```json
340 +
PolicyRule {
341 +
  pattern: "bookmarks/production"
342 +
  keys: [ KeyId ]
343 +
  threshold: 1
344 +
  require: "signed"
345 +
  allow_conflicts: false
346 +
  require_attestations: [
347 +
    {
348 +
      type: "flow/provenance/v1",
349 +
      job: "release-provenance",
350 +
      require_hermetic: true,
351 +
      signer_roles: [ "official-worker" ]
352 +
    }
353 +
  ]
354 +
}
355 +
356 +
### 8.2 Push Verification Sequence (VCS Engine Enforcement)
357 +
When a push request arrives at an Oxygen server attempting to update a
358 +
protected bookmark:
359 +
1. Object Integrity: Validate that all changes, chunks, and blobs exist and match
360 +
   their BLAKE3 hashes.
361 +
2. Attestation Resolution: Verify that an Attest object of type
362 +
   "flow/provenance/v1" is present, referencing the exact heads of the new
363 +
   State.
364 +
3. Identity Verification: Validate that the attestation's composite signature
365 +
   resolves to a KeyId listed as an authorized delegate of the repository
366 +
   policy roots.
367 +
4. Invariant Checking: Confirm that the provenance statement records
368 +
   "hermetic: true" and exit code 0.
369 +
5. Atomic Update: If validation fails at any point, the entire push is refused
370 +
   with ok = false.
371 +
372 +
## 9. Zero-Environment Secret Brokering
373 +
374 +
OxygenFlow forbids the injection of raw secret strings into process environment
375 +
tables to eliminate accidental leaking via child process dumping, procfs
376 +
reads, and verbose compiler logging.
377 +
378 +
### 9.1 Ephemeral Secret Broker
379 +
1. If a job requires a credential (e.g., signing key, cloud deployment token),
380 +
   it declares a secret mount:
381 +
     secret "deploy-token" {
382 +
         vault-ref "infra/tokens/prod"
383 +
         mount-path "/run/secrets/token"
384 +
     }
385 +
2. The runner negotiates a short-lived token lease from the configured vault.
386 +
3. The secret is mounted onto an ephemeral, in-memory ramfs location inside
387 +
   the sandbox with access mode 0400, owned exclusively by the worker process.
388 +
4. Upon process termination, the memory pages are zeroized and the token is
389 +
   marked for immediate revocation at the vault.
390 +
391 +
## 10. Conformance and Verification Requirements
392 +
393 +
A conforming OxygenFlow implementation MUST pass the following tests:
394 +
395 +
1. Injection Immunity: Attempting to supply unescaped shell metacharacters
396 +
   (; && | ` $() \n) in any job field MUST pass those characters as literal
397 +
   bytes to argv; subshells MUST NOT be spawned.
398 +
2. FastCDC Determinism: Chunks produced by artifact extraction MUST match
399 +
   the gear table cuts and BLAKE3 hashes generated by Oxygen's core chunker.
400 +
3. Commutation Hit Invariance: For any two commuting changes A and B, running
401 +
   a pipeline on State(A, B) MUST reuse cached receipts generated on State(A)
402 +
   for any job whose scope does not intersect the touched paths of B.
403 +
4. Non-Downgrade Attestation: An attestation missing the ML-DSA-65 component
404 +
   MUST be rejected by policy verification.
405 +
5. Hermetic Network Isolation: Jobs configured with network "isolated" MUST
406 +
   have outgoing TCP SYN and UDP packets dropped at the hypervisor boundary.