Skip to content

Commit bba12ea

Browse files
committed
spec: isolation gradient + unified leaf substrate (D-042/D-043)
Ordered isolation vocabulary v1.0 (none..remote) on placement; floors bake, envelopes bind: isolation_floor on placement with binding-level max-composition (PIR-016), floor-lowering as a provenance-recorded artifact edit (PIR-017), envelope in run/score provenance with grants orthogonal to level (PIR-018), the invariance + identity-boundary law (PIR-019), the sealed-memfd/JSON vars-marshaling data plane (PIR-020), and the unified tool/interpreter leaf substrate with closed kind and static grant rows plus nested cost attribution (PIR-021). New refusal codes PIR-E-VERIFY-004/-005. Additive versions.isolation stamp; no CONTRACT_PIN change; harness 67/67 green.
1 parent b24cd6f commit bba12ea

9 files changed

Lines changed: 376 additions & 15 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# 2026-08-12 — the isolation gradient (D-042) + FlexIR trust knobs as floors (D-043)
2+
3+
Ratified by maintainer decisions D-042 and D-043 (dspy decision log,
4+
`MaximeRivest-dspy/roadmap/05-decisions.md`, both 2026-08-12; design
5+
source: `roadmap/linux-isolation-notes.md` Q9–Q16 and spec
6+
`§e0-isolation`). Spec + schema + law commit; no fixtures change in this
7+
commit (L8) — the fixture families for the new refusal codes and the
8+
gradient corpus follow as their own wave.
9+
10+
What changed in this commit:
11+
12+
1. **`spec/placement.md`** — the isolation-gradient section (RATIFIED):
13+
the ordered closed vocabulary v1.0
14+
(`none < namespace < fork < fork_cgroup < fork_ratchet < sandbox <
15+
remote`), comparable by position, stamped `versions.isolation`;
16+
floors-bake/envelopes-bind; binding-level floors with
17+
max-composition (node-set byte shape deferred to the next node-set
18+
wave — the leaf object's optional `isolation_floor`);
19+
floor-lowering-as-artifact-edit with `floor_lowered_by`; run/score
20+
envelope provenance (View-2/View-3); grants orthogonal to level;
21+
invariance + identity-boundary rules; the sealed-memfd/JSON data
22+
plane; the broker egress rule (credential injection — supersedes
23+
env-passed values for below-full-trust leaves); the unified leaf
24+
substrate summary. Placement sketch gains `isolation_floor`.
25+
2. **`spec/invariants.md`** — new law family, append-only:
26+
- **PIR-015** — ordered/versioned gradient; floors bake, envelopes
27+
bind; under-floor refuses.
28+
- **PIR-016** — binding-level floors compose by max (tighten only).
29+
- **PIR-017** — floor-lowering is an artifact edit with
30+
`floor_lowered_by` provenance, never an engine flag.
31+
- **PIR-018** — envelope provenance in runs (View-2) and scores
32+
(View-3); grants orthogonal to level, unsupplied grants refuse at
33+
load.
34+
- **PIR-019** — isolation invariance; profile-unsatisfying runtimes
35+
are D-033 identity deviations, never isolation levels; divergence
36+
across levels is a candidate refusal class in optimization.
37+
- **PIR-020** — one data-plane contract, two transports
38+
(sealed-memfd Arrow local / JSON-typed wire remote); resolves the
39+
D-027 `vars`-marshaling open surface.
40+
- **PIR-021** — the unified leaf substrate: shared tool/interpreter
41+
record, closed invocation discriminant (`call`|`session`), grants
42+
as a closed static effect row, fork-scoped sessions at
43+
`fork_ratchet`+, nested cost attribution.
44+
3. **`spec/errors.md`** — the VERIFY family gains `-004` (envelope
45+
under-runs the effective floor, names leaf + floor + envelope) and
46+
`-005` (declared grant unsupplied, names grant + leaf). Additive.
47+
4. **`spec/versions.md`** — the `isolation` vocabulary entry under the
48+
extra-entry rule (same pattern as `interpreter_profile`): artifacts
49+
using the gradient stamp `versions.isolation = "1.0"`.
50+
5. **`spec/manifest.md`** — the structural-profile `isolation_floor`
51+
bullet cites the vocabulary; the canonical `vars_marshaling`
52+
resolution paragraph (PIR-020); the new unified-leaf-substrate
53+
section (D-043) with its additive byte shapes.
54+
6. **`spec/trust.md`** (PROPOSED status unchanged) — the `hardened`
55+
example's `isolation ≥ os_sandbox` updated to the D-042 vocabulary
56+
(`fork_ratchet`); ratification ask 5 marked satisfied by
57+
D-042/D-043.
58+
7. **`schema/manifest.schema.json`** — `$defs/isolation_level` (the
59+
closed ordered enum), `$defs/floor_provenance`, `$defs/grant`;
60+
`placement.isolation` closes to the enum (+ null); placement gains
61+
optional `isolation_floor` and `floor_lowered_by`; tool entries gain
62+
optional `kind` (`call`|`session`) and `grants[]`; structural
63+
interpreter entries type `isolation_floor` by the enum and gain
64+
optional `kind_invocation` and `grants[]` (`kind_invocation`, not
65+
`kind`, because bare `kind` is the legacy fused-profile
66+
discriminator and would break the entry `oneOf`). All existing
67+
fixtures validate unchanged (`isolation`/`isolation_floor` observed
68+
values are all `"none"`).
69+
8. **`schema/README.md`** — placement-block bullet updated.
70+
71+
Deliberately NOT in this commit:
72+
73+
- The node-set leaf object's optional `isolation_floor` (the
74+
binding-level floor's byte shape) — a node-set surface change, so it
75+
rides the next node-set version wave with reference + corpus + port
76+
catch-up, per the D-034/D-037/D-041 precedent. The law (PIR-016)
77+
binds now at the manifest level.
78+
- Fixture families for `PIR-E-VERIFY-004`/`-005`, the gradient corpus,
79+
and the View-2/View-3 envelope record shapes — follow-on waves.
80+
- Sidecar wire contract text (the data plane names transports, not
81+
frames) — still out of 1.0 scope.
82+
83+
Evidence: dspy decision log D-042 (isolation gradient: ordered
84+
vocabulary, revocable-vs-ratchet split, sealed-memfd data plane,
85+
floors/envelopes, invariance, identity boundary) and D-043 (FlexIR
86+
trust knobs are floor declarations, not enforcement: `code_trust` →
87+
floor aliases, enforcement at the materialize seam only, kernel-backed
88+
`lm_calls` cheapness, broker egress with credential injection,
89+
per-candidate scoring envelopes, the unified leaf substrate). Design
90+
notes: `MaximeRivest-dspy/roadmap/linux-isolation-notes.md`
91+
(conversation record, 2026-08-12).
92+
93+
Affects: `spec/placement.md`, `spec/invariants.md`, `spec/errors.md`,
94+
`spec/versions.md`, `spec/manifest.md`, `spec/trust.md`,
95+
`schema/manifest.schema.json`, `schema/README.md`.

‎schema/README.md‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,15 @@ the other.
6565
(strategies, codecs, literal_table, transforms, parsers) are the
6666
**adapter-ir contract's** to pin, not this repo's.
6767
- **Placement blocks**: `{rung, contract, endpoint_ref, default_endpoint,
68-
isolation, credential_ref}` (`spec/placement.md`); `rung` is an open
69-
string (the ladder vocabulary is not ratified as closed).
68+
isolation, isolation_floor?, floor_lowered_by?, credential_ref}`
69+
(`spec/placement.md`); `rung` is an open string (the ladder vocabulary
70+
is not ratified as closed). `isolation`/`isolation_floor` draw from the
71+
D-042 ordered closed vocabulary v1.0 (`none < namespace < fork <
72+
fork_cgroup < fork_ratchet < sandbox < remote`), stamped
73+
`versions.isolation`; `floor_lowered_by` is the PIR-017 lowering
74+
provenance. Tool entries and structural interpreter entries gain the
75+
optional D-043 unified-leaf fields (`kind`/`kind_invocation`,
76+
`grants[]`).
7077
- **Credentials**: `{name, scope}` and nothing else — a `value` key is a
7178
schema violation, making PIR-005 structural.
7279
- **Languages**: `packaged`/`authored` code identities require `language`

‎schema/manifest.schema.json‎

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,16 @@
110110
"description": "Advisory default URL for endpoint_ref, spec/placement.md placement block."
111111
},
112112
"isolation": {
113-
"type": ["string", "null"],
114-
"description": "Isolation level, spec/placement.md placement block. Observed: 'none'. No closed vocabulary ratified."
113+
"enum": ["none", "namespace", "fork", "fork_cgroup", "fork_ratchet", "sandbox", "remote", null],
114+
"description": "The receiver's isolation envelope, spec/placement.md isolation gradient (D-042, ratified 2026-08-12): the ordered closed vocabulary v1.0, comparable by position (PIR-015). Artifacts using the gradient stamp versions.isolation = '1.0' (spec/versions.md). Null reads as unset (receiver default)."
115+
},
116+
"isolation_floor": {
117+
"$ref": "#/$defs/isolation_level",
118+
"description": "Optional baked minimum isolation demand on this placement (D-042; PIR-015): the receiver's envelope may exceed the floor, never under-run it -- under-floor is a loud load refusal (PIR-E-VERIFY-004). Mirrors the interpreter structural profile's required isolation_floor."
119+
},
120+
"floor_lowered_by": {
121+
"$ref": "#/$defs/floor_provenance",
122+
"description": "Provenance of a floor-lowering edit (D-042; PIR-017): lowering a floor is an artifact edit producing a new artifact version, never an engine flag. Absent when the floor was never lowered."
115123
},
116124
"credential_ref": {
117125
"type": ["string", "null"],
@@ -121,6 +129,53 @@
121129
"required": ["rung", "contract"],
122130
"additionalProperties": false
123131
},
132+
"isolation_level": {
133+
"enum": ["none", "namespace", "fork", "fork_cgroup", "fork_ratchet", "sandbox", "remote"],
134+
"description": "The ordered isolation vocabulary v1.0 (D-042, spec/placement.md): none < namespace < fork < fork_cgroup < fork_ratchet < sandbox < remote. Ordering is normative -- 'floor' is defined by position comparison (PIR-015). Closed; extension is a versioned act (versions.isolation)."
135+
},
136+
"floor_provenance": {
137+
"type": "object",
138+
"description": "The floor-lowering provenance record (D-042 point 7; PIR-017): who lowered the floor, when, from what to what. Rides the placement block of the edited entry.",
139+
"properties": {
140+
"by": {
141+
"type": "string",
142+
"minLength": 1,
143+
"description": "Who signed for the lowered floor (PIR-014 provenance discipline)."
144+
},
145+
"date": {
146+
"type": "string",
147+
"minLength": 1,
148+
"description": "When the floor was lowered."
149+
},
150+
"old": {
151+
"$ref": "#/$defs/isolation_level",
152+
"description": "The floor before the edit."
153+
},
154+
"new": {
155+
"$ref": "#/$defs/isolation_level",
156+
"description": "The floor after the edit (strictly lower than old -- raising needs no edit; it is a binding)."
157+
}
158+
},
159+
"required": ["by", "date", "old", "new"],
160+
"additionalProperties": false
161+
},
162+
"grant": {
163+
"type": "object",
164+
"description": "One entry of the closed static effect row (D-043 unified leaf substrate; PIR-021): a capability the parent explicitly hands the leaf. Grants are orthogonal to the isolation level -- every envelope must supply every declared grant or load refuses (PIR-E-VERIFY-005; PIR-018).",
165+
"properties": {
166+
"kind": {
167+
"enum": ["fd", "broker_route"],
168+
"description": "Closed grant kind: 'fd' -- a passed/inherited file descriptor (sealed-memfd data plane, listening sockets); 'broker_route' -- a hostname route through the parent-owned broker proxy (D-043: credential injection, per-request log)."
169+
},
170+
"name": {
171+
"type": "string",
172+
"minLength": 1,
173+
"description": "The grant's name: the FD's declared role, or the broker route's hostname pattern."
174+
}
175+
},
176+
"required": ["kind", "name"],
177+
"additionalProperties": false
178+
},
124179
"code_identity": {
125180
"type": "object",
126181
"description": "A declared code identity for packaged/authored entries (PIR-003 declare-don't-discover; PIR-014 provenance). Used by LM entries' `class`.",
@@ -457,7 +512,16 @@
457512
},
458513
"authored_by": {
459514
"type": "string",
460-
"description": "PIR-014 provenance for machine-written tool code."
515+
"description": "PIR-014 provenance for machine-written tool code. Under D-043, 'optimizer' defaults the leaf's binding-level isolation floor through the receiver's trust profile (spec/trust.md)."
516+
},
517+
"kind": {
518+
"enum": ["call", "session"],
519+
"description": "Optional unified-leaf-substrate invocation discriminant (D-043; PIR-021): 'call' -- one request/response (the default when absent); 'session' -- a held stateful context, fork-scoped (lifetime = leaf span) at fork_ratchet and above."
520+
},
521+
"grants": {
522+
"type": "array",
523+
"items": {"$ref": "#/$defs/grant"},
524+
"description": "The closed static effect row (D-043; PIR-021): every capability this leaf may be handed, readable from the manifest without executing anything. Absent means no grants."
461525
}
462526
},
463527
"required": ["return_schema", "source", "deps", "language", "placement"],
@@ -533,13 +597,21 @@
533597
"description": "Declared resource limits; empty means no limits are claimed."
534598
},
535599
"isolation_floor": {
536-
"type": "string",
537-
"minLength": 1,
538-
"description": "Least isolation this identity permits; placement may move outward, never inward."
600+
"$ref": "#/$defs/isolation_level",
601+
"description": "Least isolation this identity permits, drawn from the ordered vocabulary (D-042, spec/placement.md; PIR-015); placement may move outward, never inward."
539602
},
540603
"placement": {
541604
"$ref": "#/$defs/placement",
542605
"description": "Receiver-controlled execution placement."
606+
},
607+
"kind_invocation": {
608+
"enum": ["call", "session"],
609+
"description": "Optional unified-leaf-substrate invocation discriminant (D-043; PIR-021); interpreters default to 'session'. Named kind_invocation here because 'kind' is the legacy fused-profile discriminator."
610+
},
611+
"grants": {
612+
"type": "array",
613+
"items": {"$ref": "#/$defs/grant"},
614+
"description": "The closed static effect row (D-043; PIR-021). Absent means no grants."
543615
}
544616
},
545617
"required": [

‎spec/errors.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Python type names).
1414
| `MANIFEST` | parse/schema/malformed | `-001` unreadable JSON · `-002` schema violation naming path · `-003` missing versions block |
1515
| `VERSION` | versions block mismatches | `-001` unknown major, names entry + both versions |
1616
| `LINK` | dangling refs | `-001` binding names absent pool entry · `-002` delta without entry |
17-
| `VERIFY` | declared-tier verification | `-001` credential unresolved (names name+scope) · `-002` endpoint serves wrong identity · `-003` system dep missing |
17+
| `VERIFY` | declared-tier verification | `-001` credential unresolved (names name+scope) · `-002` endpoint serves wrong identity · `-003` system dep missing · `-004` envelope under-runs the effective isolation floor (names leaf + floor + envelope; D-042, PIR-015/016) · `-005` declared grant unsupplied by the envelope (names grant + leaf; D-042/D-043, PIR-018) |
1818
| `NODE` | node-set compile refusal | `-001` un-whitelisted node (names node kind + location) · `-002` unresolved call (names target + location) · `-003` record-splat key refused — splat/kwarg collision or callee-unaccepted key (names key + location; D-041) · `-004` write to the read-only input record (names record + location; D-041) |
1919
| `LANG` | cross-language / rung-walk | `-001` no satisfiable rung (names component + language + rungs tried). Adapter-layer code never enters the walk (D-026) — its refusal is `PROFILE`, not `LANG` |
2020
| `PROFILE` | profile predicate | `-001` clause violated (names clause id) · `-002` authored-origin adapter code present (the D-026 refusal) |

‎spec/invariants.md‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,73 @@ design-intent style with ratification date.
8686
shipped score and the baked metric re-warrants. WHY (dspy L11;
8787
IR-program-spec §e0-binding).
8888

89+
## Isolation discipline (D-042/D-043, ratified 2026-08-12)
90+
91+
- **PIR-015 — The isolation gradient is ordered and versioned; floors
92+
bake, envelopes bind.** `isolation` values come from the closed ordered
93+
vocabulary `none < namespace < fork < fork_cgroup < fork_ratchet <
94+
sandbox < remote` (v1.0, stamped `versions.isolation`); comparison is by
95+
position. The artifact bakes a *floor* (`isolation_floor` on the
96+
interpreter structural profile and on tool placement); the receiver's
97+
actual envelope is a *binding* that may exceed the floor, never
98+
under-run it — under-floor is a loud load refusal
99+
(`PIR-E-VERIFY-004`). The gradient is an axis orthogonal to the rung.
100+
WHY (D-042, 2026-08-12): the 3-value enum could not express the real
101+
continuum from one-RAM/one-process to full lockdown, and had no floor
102+
semantics for optimizer-authored code.
103+
- **PIR-016 — Binding-level floors compose by max.** A leaf's binding may
104+
carry an `isolation_floor` override; the effective floor at a leaf =
105+
max(entry floor, binding floor). Floors tighten per binding, never
106+
loosen. WHY (D-042 point 6): per-leaf trust distinctions (author's
107+
helper vs optimizer-generated body on the same runtime entry) must
108+
never force a floor-fork of a byte-identical pool entry — sharing an
109+
entry is a stated fact about identity.
110+
- **PIR-017 — Lowering a floor is an artifact edit, never an engine
111+
flag.** Lowering produces a new artifact version with
112+
`floor_lowered_by {by, date, old, new}` in provenance; raising the
113+
envelope stays a binding. WHY (D-042 point 7): a runtime override flag
114+
would make the artifact lie about how it runs; an edit is visible in a
115+
diff, auditable, and scoped to one copy.
116+
- **PIR-018 — Envelope provenance; grants are orthogonal to level.**
117+
Every run records the actual envelope used per leaf (View-2); every
118+
score carries the envelope it was measured under (View-3). A leaf's
119+
declared grants must be supplied by the envelope at *any* level or load
120+
refuses (`PIR-E-VERIFY-005`) — "stopped working under stricter
121+
isolation" is never a silent runtime surprise. WHY (D-042 point 7,
122+
D-043 point 5): the record is what makes the invariance law a checkable
123+
claim; optimizer trajectories carry the same per-candidate envelope.
124+
- **PIR-019 — Isolation invariance; the identity boundary.** A leaf must
125+
behave identically at every isolation level; a level change that
126+
changes behavior indicts the leaf (undeclared side channels), never the
127+
level. Every level runs the leaf's declared interpreter profile (D-033)
128+
unchanged; a runtime that cannot satisfy the profile is an *identity
129+
deviation* under D-033 (refusal, or a recorded deviation that detaches
130+
scores), never a higher isolation level — `remote` means the same
131+
profile satisfied elsewhere. In optimization, a divergence across
132+
levels is a candidate refusal class (D-043 point 5). WHY (D-042 points
133+
5 and 8): this is what keeps the gradient a binding rather than an
134+
identity axis, so scores stay warranted across isolation re-placement.
135+
- **PIR-020 — One data-plane contract, two transports.** Local-rung leaf
136+
inputs/outputs travel as sealed shared memory (memfd + write-seal,
137+
Arrow IPC), the FD passed as the capability grant; remote rungs use the
138+
JSON-typed wire form. The leaf's typed contract is identical over both.
139+
This is the resolution of the D-027 open `vars`-marshaling surface.
140+
WHY (D-042 point 4): sealing makes inputs immutable to hostile bodies;
141+
an FD crosses every wall on the gradient, so data sharing costs nothing
142+
in isolation strength.
143+
- **PIR-021 — The unified leaf substrate.** Tools and interpreters share
144+
one leaf record shape: a closed invocation discriminant (`call` — one
145+
request/response — | `session` — a held stateful context) and grants as
146+
a closed static effect row (`fd` | `broker_route`), readable from the
147+
manifest without executing anything. Session leaves at `fork_ratchet`+
148+
are fork-scoped: lifetime = leaf span. Nested cost attribution: an LM
149+
call made through a grant bridge attributes to both the session leaf
150+
that made it and the underlying predictor it reached, transitively.
151+
WHY (D-043 point 6): interpreter and tool were always two spellings of
152+
"a leaf that executes a body under a profile"; every knob (floor,
153+
grants, placement, authorship) lands on both, and static grant rows
154+
keep the trust surface auditable without simulation.
155+
89156
---
90157

91158
Status: DRAFT, unratified. Numbering starts here; append only.

0 commit comments

Comments
 (0)