1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# Default safety levels — the behavioral capability model
# (docs/design/behavioral-taxonomy-v1.4.md §4.3). Authored from the spec and
# compiled to `engine::level::Level` by `engine::authoring`.
#
# The ladder, locked → open:
#
# paranoid → reader → editor → developer ─┬─→ local-admin ─┐
# └─→ network-admin ┴─→ yolo
#
# The first four are a linear chain; local-admin and network-admin are INCOMPARABLE
# siblings above developer — same trust tier, opposite directions. local-admin flexes
# DOWN into this machine (elevated authority, machine/device locus, install/reconfigure);
# network-admin flexes OUT to other hosts (remote reach, outbound network, metered cost).
# Neither is "more permissive" than the other; they open disjoint facet regions. That is
# the thing the old linear `Inert < SafeRead < SafeWrite` enum could not express — a
# level is now a predicate over capability-space, so two levels can be siblings.
#
# The reversibility cap is the spine: every level BELOW yolo caps destruction at
# `reversibility <= effortful` (recoverable with real work). Only yolo lifts it to
# `irreversible` — so `destroy · irreversible` (terraform destroy, mkfs, aws rds delete)
# is reserved for yolo, on any locus, local or remote. That single cap is what keeps
# permanent, no-recovery-path destruction out of both admin flavors.
#
# A clause constrains only the facets that discriminate the level; an omitted facet is
# unconstrained. Ordinal facets take "<= term" / ">= term" / "term" (exact); categorical
# facets take a term or a list of terms. Allow clauses use ceilings (`<=`) and exact
# bounds only at a ladder's minimum, so lowering any facet never flips admit→deny
# (facet-monotonicity, checked by `authoring::authored_levels_are_facet_monotone`).
[]
# Barely touches anything: --version, --help, arithmetic, > /dev/null. Doesn't even
# open your files. The floor — maximally cautious; the opposite pole from yolo.
[[]]
= ["observe"]
= { = "<= temp", = "none" }
= "<= single"
= "none"
= { = "transient" }
= { = "<= local-process" }
= { = "none" }
= { = "none" }
= "<= self"
= "user"
= "none"
[]
# Observe state — LOCAL and REMOTE alike. Local: git status, ls, cat ./notes, grep -r src/.
# Remote: a pure fetch (curl GET, `koyeb apps list`) — a read is a read regardless of where the
# data lives, and the "network part" (an arbitrary endpoint, a response entering the model) is a
# prompt-injection/model concern, out of scope here (like $PATH/sandbox). Only `paranoid` blocks
# network. The read/write LOCUS distinction that DOES matter is on the WRITE side (editor/developer
# stay local; remote writes are network-admin) — reads don't earn that friction.
#
# Bounds still hold, fail-closed: local content is bounded by LOCUS (home/absolute `cat ~/.ssh` is
# above this level, denied by locus); `secret <= uses-ambient` excludes credential EXTRACTION;
# `payload <= fetches` allows a GET but NOT `sends-host-data` — an exfil request (`curl -d @secret`)
# carries host data OUT and is denied, and a fetch whose URL splices in a secret dies on the inner
# secret read. So the network read is a pure fetch, never an egress.
= "paranoid"
[[]]
= ["observe"]
# `<= worktree-trusted` already admits a SIBLING project read: `adjacent` sits just BELOW
# worktree-trusted in the ladder, so `cat ../branchdiff/x` (a peer repo under the same parent) reads
# here without widening the cap. A sibling's own hidden files (.env/.git/.aws) never classify
# `adjacent` (region shield + hidden-component guard), so only ordinary peer source is read. `user`
# (~, keychain) and above stay denied. Sibling-ness is a structural resolver test, NOT a named
# directory list — so it doesn't reintroduce a region admit-map.
= { = "<= worktree-trusted", = "<= arbitrary" }
= "none"
= { = "transient" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "<= outbound", = "<= arbitrary", = "<= fetches" }
= "<= self"
= "user"
# A read returns metadata (describe/list) or structured records (a query result / db dump) — NOT
# arbitrary opaque STORED CONTENT. `retrieval <= record` denies `bulk-content` (an S3 object body, an
# EBS block, a Glacier archive): unassessable bytes that routinely hold a secrets file / key / dump.
# That bulk egress earns network-admin (elevated remote data flow), not the everyday reader tier —
# the proportionate middle the `bulk-object-read` archetype needs. See archetypes.md §5 (#1).
= "<= record"
[]
# Also create/mutate ordinary local data with no downstream execution: touch, echo >
# file, git commit. No reconfiguring/installing, no mass ops, no network. Nothing it does
# is hard to undo.
= "reader"
[[]]
= ["observe", "create", "mutate"]
= { = "<= worktree", = "none" }
= "<= bounded"
= "<= recoverable"
= { = "<= data" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= caller-inline"
= "user"
[]
# The everyday dev box. Runs your project and its pinned dependencies, edits and deletes
# your OWN files, uses the tools you use — but stops short of anything stupidly
# destructive (irreversible), privileged, or reaching off this machine. A developer knows
# how to reverse an `rm -rf ./node_modules` or a `sed -i`; that's the trust this level
# assumes. (The supply-chain build/install clause and the outbound-fetch clause land with
# their resolvers — npm, cargo, git — in later commits, when they can be exercised; the
# install clause will require BOTH a pinned source AND install scripts disabled.)
= "editor"
# Delete your own project files: rm ./f, rm -rf ./node_modules. The golden-set boundary is
# create/overwrite (editor) vs DESTROY (developer) — overwriting your own file (echo > f,
# cp ./a ./b) is recoverable and stays at editor; only deletion, effortful to undo, waits
# for developer. Recursive and effortful deletion is admitted, but only WITHIN the worktree
# — .git/ and home/system sit at worktree-trusted+ and stay denied by locus. IRREVERSIBLE
# deletion (shred, mkfs) exceeds `<= effortful` and waits for yolo.
[[]]
= ["destroy"]
= { = "<= worktree", = "none" }
= "<= unbounded"
= "<= effortful"
= { = "<= data" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= self"
= "user"
# Patch a SIBLING project — create/mutate (NOT destroy) up to the `adjacent` locus: the common
# cross-repo move (`echo >> ../branchdiff/fix.rs`, `sed -i ../branchdiff/x`). A developer trusted to
# edit their own tree is trusted to patch a co-located peer repo. DESTROY is deliberately withheld —
# `rm -rf ../otherrepo` is not a "quick patch"; the destroy clause above stays `<= worktree`, so a
# sibling delete denies (waits for a higher level / explicit grant). Sibling hidden files (.env/.git)
# never classify `adjacent` (region shield), so a hook/secret write stays frozen. editor does NOT
# inherit this (its writes stay `<= worktree`) — sibling writes begin at developer.
[[]]
= ["create", "mutate"]
= { = "<= adjacent", = "none" }
= "<= unbounded"
= "<= effortful"
= { = "<= data" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= self"
= "user"
# Run the workspace's OWN code — the dev loop (cargo run, go run ., bash ./x.sh, python
# ./s.py). The discriminator is the EXECUTOR LOCUS, not the effect: a range
# `[sandbox-scope, worktree-trusted]` admits worktree-local code but excludes `temp`
# (/tmp/x.sh is staged/downloaded, foreign) and `user`/`machine` (~/x.sh, /usr/local/bin/x).
# Inline code carries no file locus (`process`, below the band) and so denies here; opaque
# inline (python -c) is denied at the resolver too. `execution <= caller-file` keeps
# ambient/network-sourced execution out of this clause. See
# docs/design/behavioral-taxonomy-execution-origin.md.
[[]]
= ["execute"]
= { = ">= sandbox-scope, <= worktree-trusted", = "none" }
= "<= unbounded"
= "<= effortful"
= { = "<= data" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= caller-file"
= "user"
# Install pinned dependencies WITHOUT running their code — the `npm ci --ignore-scripts` shape: a
# lockfile-pinned, scripts-OFF install. It FETCHES packages (network) and WRITES them into the
# worktree (node_modules) with `persistence = installing` — above editor's `data` ceiling, since a
# future `node app` uses them — but it runs NO foreign code at install (`execution <= self`: npm
# itself runs; the fetched code is inert data until you later run your own program, a separate
# command). This is the "pinned source + scripts disabled" install the level's header promises. The
# safety is enforced at the RESOLVER, which emits THIS shape only when the command is BOTH pinned AND
# scripts-off; anything less — a floating version, OR install scripts enabled — emits `execution =
# network-sourced` (the `supply-chain-build` archetype), which has no home below yolo. So the
# reproducible no-code-runs install is a dev-loop staple here, while the supply-chain surface is not.
# All `<=` ceilings (execution capped at `self`), so it stays facet-monotone — the scripts-ON install
# is a DIFFERENT, higher region, not a floored corner of this one.
# `<= worktree` (NOT worktree-trusted): the install writes node_modules / lockfiles, ordinary worktree
# files. `.git/`, `.envrc`, and hooks are `worktree-trusted` — write-frozen (code injection) — and stay
# denied here, exactly as for every other write clause.
[[]]
= ["create", "mutate"]
= { = "<= worktree", = "none" }
= "<= unbounded"
= "user"
= "<= effortful"
= { = "<= installing" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "<= outbound", = "<= arbitrary", = "<= fetches" }
= "<= self"
= "<= local-resource"
[]
# Developer, but trusted to run THIS machine as an administrator. Flexes DOWN into the
# box: elevated/root authority (sudo, doas), ORDINARY machine locus (/etc app config,
# /usr/local, services, mounts), install/reconfigure persistence (systemctl enable, system
# package installs, launchd). Blast radius = this host's everyday admin surface. It never
# reaches the network. Held BACK to yolo: the SYSTEM-INTEGRITY substrate (identity/auth/
# boot/loader — writing /etc/passwd, /etc/sudoers, /boot is compromise-complete, locus >
# machine), raw devices and kernel-module load (locus > machine), setuid / run-as-another
# user (authority > root), and irreversible destruction (reversibility > effortful — a disk
# wipe is not "admin", it's yolo). The `machine`-vs-`system-integrity` split is the point: a
# service restart or an app-config edit is admin; owning the machine's trust root is not.
= "developer"
# Privileged local state: sudo file edits under /etc, service control, package installs,
# mounts. Destroy is admitted up to `machine` but only at `<= effortful` — the integrity
# substrate, raw devices (`mkfs`/`shred`/`dd of=/dev/sdX`), and anything irreversible stay at yolo.
[[]]
= ["observe", "create", "mutate", "destroy", "configure", "control", "authorize"]
= { = "<= machine", = "none" }
= "<= unbounded"
= "<= root"
= "<= effortful"
= { = "<= installing" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= caller-file"
= "<= local-resource"
# Run system binaries and your own scripts AS root (sudo systemctl, sudo ./deploy.sh).
# Executor locus up to `machine` (system binaries), still `execution <= caller-file`, so
# running network-sourced code as root stays at yolo.
[[]]
= ["execute"]
= { = "<= machine", = "none" }
= "<= unbounded"
= "<= root"
= "<= effortful"
= { = "<= installing" }
= { = "<= local-process" }
= { = "<= uses-ambient" }
= { = "none" }
= "<= caller-file"
= "<= local-resource"
[]
# Developer, but trusted to operate YOUR remotes. Flexes OUT to other hosts: remote reach
# (any host/cluster/cloud), outbound network carrying host data (push, deploy, upload),
# metered/quota cost (provision billable resources). Blast radius = your cloud/clusters,
# not this machine's system files — it runs as your plain local user and never sudo's the
# box. Held BACK to yolo: IRREVERSIBLE remote destruction (terraform destroy, aws rds
# delete, kubectl delete pvc — reversibility > effortful), inbound-listen servers,
# TRANSMITTING A SECRET off-box (secret > uses-ambient — credential exfil), and running
# network-sourced code (a pulled container image — that awaits the supply-chain clause).
#
# `disclosure.audience` is recorded up to `public`, NOT gated: publishing content you
# authored (git push to a public repo you set up, npm publish) is the intended act of
# someone operating their remotes, not a yolo-only recklessness. The confidentiality danger
# is graded by CONTENT — the `secret` ceiling above — not by how public the destination is
# (behavioral-taxonomy-exposure.md §3, §7). Destination-trust (established vs inline vs
# dynamic target — §4) is a separate, resolver-side axis still to be designed.
= "developer"
[[]]
= ["observe", "create", "mutate", "destroy", "communicate", "configure", "control", "authorize"]
= { = "<= worktree-trusted", = "<= arbitrary", = "<= literal" }
= "<= unbounded"
# Admits `bulk-content` retrieval (an object/block/archive body) — the proportionate home for bulk
# remote data egress that reader/editor/developer refuse (`retrieval <= record`). Elevated, but NOT
# credential-grade (`secret <= uses-ambient` still holds, so a credential read stays yolo). See #1.
= "<= bulk-content"
= "user"
= "<= effortful"
= { = "<= reconfiguring" }
= { = "<= public" }
= { = "<= uses-ambient" }
= { = "<= outbound", = "<= arbitrary", = "<= sends-host-data" }
= "<= caller-file"
= "<= quota"
[]
# No limits — it allows ALMOST everything, and it does so POSITIVELY, with no `deny`. yolo is a
# base level (no `extends`). The one thing it withholds — unbounded irreversible destruction,
# `rm -rf /` — is never carved IN, exactly the way every level below already excludes it (nothing
# admits it). A UNION of allow clauses covers everything else; their only gap is the catastrophe
# corner `destroy · irreversible · unbounded`. This is a union, not a subtraction: a capability is
# admitted if ANY clause admits it, and no clause admits the corner. An omitted facet is
# unconstrained (admits any value), so these three short clauses are as permissive as they read.
#
# Non-destroy operations: unrestricted — any locus, authority, network, execution, reversibility.
[[]]
= ["observe", "create", "mutate", "execute", "communicate", "configure", "authorize", "control"]
# Destruction that is RECOVERABLE (at any scale) ...
[[]]
= ["destroy"]
= "<= effortful"
# ... OR BOUNDED (at any reversibility). The union of these two admits every destroy except the
# one that is BOTH irreversible AND unbounded — terraform destroy (bounded) and mkfs (single
# device) stay in, `rm -rf /` (irreversible + unbounded) is the sole capability nothing admits.
[[]]
= ["destroy"]
= "<= bounded"