Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
52f3da6
Fabric served door refuses unrostered writers: roster derived from th…
Sep 27, 2026
dcbd879
WIP: fabric door on a unix socket with kernel-attested peers
Sep 27, 2026
5fa60e8
Delete the uncalled fabric_served_writer_admission wrapper (review 71…
Sep 27, 2026
50afc4c
Merge PR 1's review fix into the socket branch
Sep 27, 2026
485c45a
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Sep 27, 2026
1cd3e24
Typed writer refusal, placement-derived receipt bindings, and an hone…
Sep 28, 2026
de5663a
Merge remote-tracking branch 'origin/session/jolly-owl-158' into sess…
Sep 28, 2026
36fc94f
Door: service-only store areas, unmanaged entries, drop row retired b…
Sep 28, 2026
e4e1e6e
Merge PR 1 (typed writer refusal) into the socket branch; the door's …
Sep 28, 2026
2376e3b
Move the target-model source serializer out of v2.compiler.translate …
Sep 28, 2026
b5e9a90
Move the socket-door annotations to module-item grain (§4c)
Sep 28, 2026
e8d4fed
Seed-growth receipt for the socket door's hand Rust (review 72010)
Sep 28, 2026
5a136ef
Regenerate design-rung-drops.md for the retired fabric write-wall row
Sep 28, 2026
e22248e
Share the broker digest substitution between both receipt arms; the r…
Sep 28, 2026
e04ed7f
Merge main (with #12451) into the socket branch
Sep 28, 2026
1d2d88a
Regenerate design-rung-drops.md after merging main
Sep 28, 2026
c81cc22
Drop the merge-duplicated wire claim; it now also covers the peer ref…
Sep 28, 2026
4e9645c
Dark-install claims read their producers; one inhabitance claim rende…
Sep 28, 2026
376f926
Carry the bash-fold grammar once and serialize the row a leaf selected
Sep 28, 2026
f261ff2
Merge main (#12483 landed)
Sep 28, 2026
0d8f3df
Merge session/jolly-bee-43 (#12520, dark-install render cost) into th…
Sep 28, 2026
cdf7695
Regenerate design-rung-drops.md after the merge
Sep 28, 2026
6c6a238
Merge main into the socket branch (broker locus now privileged-only; …
Sep 28, 2026
575b66e
Merge main (#12520 landed) into the socket branch
Sep 28, 2026
1e74401
Regenerate design-rung-drops.md after merging main
Sep 28, 2026
6dae9cd
Declare the dark-install first-reader eval-step drop (operator ruling…
Sep 29, 2026
78c2e4c
Merge remote-tracking branch 'origin/main' into session/jolly-owl-158…
Sep 29, 2026
b67490b
Regenerate gunbc_cli_dispatch_surface.rs for the serve --unix-socket …
Sep 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions dag/extdeps/http/client.dag
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ fn http_client_get_argv(url: NonEmptyStr, max_time: Second) -> List<String> {
// carries the transport outcome (6 could not resolve, 7 could not connect, 28 timed out, 35 TLS
// handshake failed -- curl(1) EXIT CODES), and a consumer classifies it rather than reading the
// stderr text.
// PostStdinWithinUnixSocket, THE SAME BOUNDED POST OVER A UNIX SOCKET (curl --unix-socket, curl(1)):
// the URL still names the scheme, authority and path the server routes on, but the connection is
// made to the socket file and the kernel attests the caller to the server. The exit codes are
// PostStdinWithin's; a socket that is absent or not traversable is exit 7, could not connect.
service http.Client {
operation Get {
input { url: NonEmptyStr }
Expand Down Expand Up @@ -201,6 +205,27 @@ service http.Client {
}
}

operation PostStdinWithinUnixSocket {
input { socket: NonEmptyStr, url: NonEmptyStr, request_body: String, connect_seconds: NonEmptyStr, max_seconds: NonEmptyStr }
output {
exit_code: Int from "exit_code"
success: Bool from "exit_success"
body: String from "stdout"
stderr: String from "stderr"
}
transport shell {
argv: ["curl", "-sS", "--unix-socket", "{socket}", "--connect-timeout", "{connect_seconds}", "--max-time", "{max_seconds}", "-X", "POST", "--data-binary", "@-", "-w", "\n%\{http_code\}", "{url}"]
stdin: request_body
}
exit {
0 => Unit
nonzero => String "curl POST over a unix socket did not complete"
}
mock_response {
0 => { exit_code: 7, success: false, body: "", stderr: "hermetic: no live socket" } "hermetic: a transport that never connects, so a caller answers unreachable rather than fabricating a reply"
}
}

operation PostJsonFromFile {
input { url: NonEmptyStr, request_body_file: NonEmptyStr, max_seconds: NonEmptyStr }
output { body: String from "stdout", success: Bool from "exit_success" }
Expand Down
14 changes: 13 additions & 1 deletion dag/extdeps/tailscale/serve.dag
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,20 @@ fn tailscale_serve_status_funnel_listeners(status_json: String) -> TailscaleFunn
}
}

// THE BACKEND IS TAILSCALE'S OWN TARGET WORD: a loopback port, or a unix socket spelled
// "unix:<path>" (tailscale ipn/serve.go ExpandProxyTargetValue: `unix:` is handled before URL
// parsing and kept verbatim as the handler's Proxy; since v1.98.9 a unix target may be configured
// only by root, TS-2026-005). So the status projection of a unix target is the target itself, and
// of a port it is the http://127.0.0.1 URL the docs state is the only proxy form for ports.
data tailscale_serve_unix_target_prefix: String = "unix:"

fn tailscale_serve_unix_target(path: NonEmptyStr) -> NonEmptyStr {
concat(tailscale_serve_unix_target_prefix, path as String) as NonEmptyStr
}

fn tailscale_serve_proxy_url(endpoint: TailscaleServeEndpoint) -> String {
concat("http://127.0.0.1:", endpoint.backend as String)
if starts_with(s: endpoint.backend as String, prefix: tailscale_serve_unix_target_prefix) { endpoint.backend as String }
else { concat("http://127.0.0.1:", endpoint.backend as String) }
}

fn tailscale_serve_mount_status_key(mount: TailscaleServeMount) -> String {
Expand Down
11 changes: 11 additions & 0 deletions dag/gunbc/cli_dispatch_surface.dag
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,17 @@ fn gunbc_cli_subcommands() -> List<CliSubcommandRow> {
doc: [],
emission: CarriedByGeneratedDispatch
},
CliOptionRow {
field: "unix_socket",
long: "unix-socket",
value: CliTextValue { text_default: none },
arity: CliAtMostOne,
doc: [
"Listen on this unix socket INSTEAD of --host/--port. Each request's",
"kernel-attested peer (SO_PEERCRED) is handed to the handler as peer_user."
],
emission: CarriedByGeneratedDispatch
},
CliOptionRow {
field: "release_revision",
long: "release-revision",
Expand Down
75 changes: 58 additions & 17 deletions dag/gunbc/fabric/fabric_storage_client.dag
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,26 @@ import gunbc.fabric_storage_wire {
import gunbc.fabric_storage_file_store {
FabricStorageFileRoot, fabric_storage_file_head, fabric_storage_file_put, fabric_storage_file_advance, fabric_storage_file_closure,
}
import gunbc.fabric_storage_placement { FabricStoragePlacement, FabricStoragePlaced, FabricStorageUnplaced, fabric_storage_placed_file_root, FabricStoragePlacedRootReady, FabricStoragePlacedRootRefused }
import gunbc.fabric_storage_placement { FabricStoragePlacement, FabricStoragePlaced, FabricStorageUnplaced, fabric_storage_door_socket, fabric_storage_route_prefix }
import product.placement_supply { HostIdentity, host_identity_eq }

// THE FABRIC DB AS A CALLER REACHES IT: std.fabric_storage's four operations, each bound to one of two
// handlers. The binding is realization and sits here, at the periphery (DESIGN 3: the dispatch that
// selects a realization is itself realization):
// THE FABRIC DB AS A CALLER REACHES IT: std.fabric_storage's four operations, each bound to one of
// three handlers. The binding is realization and sits here, at the periphery (DESIGN 3: the dispatch
// that selects a realization is itself realization):
//
// FabricStorageLocalFiles the caller IS the placed host; the file store runs in process.
// FabricStorageServed every other host; one bounded HTTPS POST to the placed host's endpoint,
// answered in the one wire form.
// FabricStorageDoorSocket the caller IS the placed host; one bounded POST to the door's unix
// socket, where the kernel attests the caller to the door.
// FabricStorageServed every other host; one bounded HTTPS POST to the placed host's endpoint
// (tailscale serve, which proxies to the same socket).
// FabricStorageLocalFiles the file store in process, over a root the caller names. NO PLACEMENT
// DERIVES IT: it is the realization the door itself runs, and the one a
// claim or instrument uses over its own temp root. Since 2026-09-27 the
// placed host's writers reach the placed store only through the door
// (operator ruling relayed by proud-deer-538), so every write to it passes
// one admission (gunbc.fabric_storage_serve).
//
// There is no third binding and no fallback between them: a served call that cannot reach the
// endpoint answers FabricStoreUnreachable and the caller refuses -- it never reads a local copy,
// because no host but the placement holds one.
// There is no fallback between them: a call that cannot reach its door answers
// FabricStoreUnreachable and the caller refuses -- it never reads a local copy.
//
// UNREACHABLE IS DECIDED HERE, FROM THE TRANSPORT, BEFORE ANY REPLY EXISTS. curl's exit status is
// classified by extdeps.tools.curl; any nonzero status is the store not being reached. A reply with
Expand All @@ -42,20 +48,17 @@ import product.placement_supply { HostIdentity, host_identity_eq }
// arm. Only a 200 body is decoded, and decoding refuses anything that is not fabric_storage/1.
type FabricStorageBinding
= FabricStorageLocalFiles { root: FabricStorageFileRoot }
| FabricStorageDoorSocket { socket: NonEmptyStr }
| FabricStorageServed { endpoint: NonEmptyStr }
| FabricStorageBindingUnplaced
| FabricStorageBindingRefused { detail: NonEmptyStr }

fn fabric_storage_binding_for(placement: FabricStoragePlacement, executor: HostIdentity) -> FabricStorageBinding {
match placement {
FabricStorageUnplaced => FabricStorageBindingUnplaced
FabricStoragePlaced { host: h, store_root: r, endpoint: e } =>
if host_identity_eq(a: h, b: executor) {
match fabric_storage_placed_file_root(store_root: r) {
FabricStoragePlacedRootReady { root } => FabricStorageLocalFiles { root: root }
FabricStoragePlacedRootRefused { detail } => FabricStorageBindingRefused { detail: detail }
}
} else { FabricStorageServed { endpoint: e } }
FabricStoragePlaced { host: h, store_root: _, endpoint: e } =>
if host_identity_eq(a: h, b: executor) { FabricStorageDoorSocket { socket: fabric_storage_door_socket() } }
else { FabricStorageServed { endpoint: e } }
}
}

Expand Down Expand Up @@ -102,6 +105,19 @@ fn served_post(endpoint: NonEmptyStr, operation: String, request: String) -> Ser
served_reply_from(exit_code: r.exit_code, stdout: r.body, stderr: r.stderr)
}

// The socket carries the same protocol at the same route; the authority in the URL is only what
// HTTP requires to be present, and the door routes on the path alone.
fn door_post(socket: NonEmptyStr, operation: String, request: String) -> ServedReply {
let r = http.Client.PostStdinWithinUnixSocket(
socket: socket,
url: join(["http://localhost", fabric_storage_route_prefix, "/", operation], "") as NonEmptyStr,
request_body: request,
connect_seconds: http_client_max_time_flag(max_time: fabric_storage_connect_bound),
max_seconds: http_client_max_time_flag(max_time: fabric_storage_request_bound),
)
served_reply_from(exit_code: r.exit_code, stdout: r.body, stderr: r.stderr)
}

fn expectation_request_words(expected: FabricHeadExpectation) -> String {
match expected {
ExpectHeadAbsent => "absent"
Expand All @@ -116,6 +132,11 @@ fn fabric_storage_head(binding: FabricStorageBinding, name: NonEmptyStr) -> Fabr
FabricStorageBindingUnplaced => FabricHeadReadRefused { fault: FabricStoreUnreachable { detail: fabric_storage_unplaced_detail } }
FabricStorageBindingRefused { detail: d } => FabricHeadReadRefused { fault: FabricStoreUnreachable { detail: d } }
FabricStorageLocalFiles { root: r } => fabric_storage_file_head(root: r, name: name)
FabricStorageDoorSocket { socket: k } =>
match door_post(socket: k, operation: "head", request: name as String) {
ServedFault { fault: f } => FabricHeadReadRefused { fault: f }
ServedAnswered { body: b } => fabric_storage_unwire_head(text: b)
}
FabricStorageServed { endpoint: e } =>
match served_post(endpoint: e, operation: "head", request: name as String) {
ServedFault { fault: f } => FabricHeadReadRefused { fault: f }
Expand All @@ -129,6 +150,11 @@ fn fabric_storage_put(binding: FabricStorageBinding, object: FabricObject) -> Fa
FabricStorageBindingUnplaced => FabricPutRefused { fault: FabricStoreUnreachable { detail: fabric_storage_unplaced_detail } }
FabricStorageBindingRefused { detail: d } => FabricPutRefused { fault: FabricStoreUnreachable { detail: d } }
FabricStorageLocalFiles { root: r } => fabric_storage_file_put(root: r, object: object)
FabricStorageDoorSocket { socket: k } =>
match door_post(socket: k, operation: "put", request: fabric_object_preimage(object: object) as String) {
ServedFault { fault: f } => FabricPutRefused { fault: f }
ServedAnswered { body: b } => fabric_storage_unwire_put(text: b)
}
FabricStorageServed { endpoint: e } =>
match served_post(endpoint: e, operation: "put", request: fabric_object_preimage(object: object) as String) {
ServedFault { fault: f } => FabricPutRefused { fault: f }
Expand All @@ -142,6 +168,11 @@ fn fabric_storage_advance(binding: FabricStorageBinding, name: NonEmptyStr, expe
FabricStorageBindingUnplaced => FabricHeadAdvanceRefused { fault: FabricStoreUnreachable { detail: fabric_storage_unplaced_detail } }
FabricStorageBindingRefused { detail: d } => FabricHeadAdvanceRefused { fault: FabricStoreUnreachable { detail: d } }
FabricStorageLocalFiles { root: r } => fabric_storage_file_advance(root: r, name: name, expected: expected, target: target)
FabricStorageDoorSocket { socket: k } =>
match door_post(socket: k, operation: "advance", request: join([name as String, " ", expectation_request_words(expected: expected), " ", fabric_object_ref_wire(object: target) as String], "")) {
ServedFault { fault: f } => FabricHeadAdvanceRefused { fault: f }
ServedAnswered { body: b } => fabric_storage_unwire_advance(text: b)
}
FabricStorageServed { endpoint: e } =>
match served_post(endpoint: e, operation: "advance", request: join([name as String, " ", expectation_request_words(expected: expected), " ", fabric_object_ref_wire(object: target) as String], "")) {
ServedFault { fault: f } => FabricHeadAdvanceRefused { fault: f }
Expand All @@ -155,6 +186,11 @@ fn fabric_storage_closure(binding: FabricStorageBinding, name: NonEmptyStr, boun
FabricStorageBindingUnplaced => FabricClosureRefused { fault: FabricStoreUnreachable { detail: fabric_storage_unplaced_detail } }
FabricStorageBindingRefused { detail: d } => FabricClosureRefused { fault: FabricStoreUnreachable { detail: d } }
FabricStorageLocalFiles { root: r } => fabric_storage_file_closure(root: r, name: name, bound: bound)
FabricStorageDoorSocket { socket: k } =>
match door_post(socket: k, operation: "closure", request: join([name as String, " ", to_string(bound)], "")) {
ServedFault { fault: f } => FabricClosureRefused { fault: f }
ServedAnswered { body: b } => fabric_storage_unwire_closure(text: b)
}
FabricStorageServed { endpoint: e } =>
match served_post(endpoint: e, operation: "closure", request: join([name as String, " ", to_string(bound)], "")) {
ServedFault { fault: f } => FabricClosureRefused { fault: f }
Expand All @@ -173,6 +209,11 @@ fn fabric_storage_presented_identity(binding: FabricStorageBinding) -> FabricIde
FabricStorageBindingUnplaced => FabricIdentityReadRefused { fault: FabricStoreUnreachable { detail: fabric_storage_unplaced_detail } }
FabricStorageBindingRefused { detail: d } => FabricIdentityReadRefused { fault: FabricStoreUnreachable { detail: d } }
FabricStorageLocalFiles { root: _ } => FabricIdentityUnproxied
FabricStorageDoorSocket { socket: k } =>
match door_post(socket: k, operation: "identity", request: "") {
ServedFault { fault: f } => FabricIdentityReadRefused { fault: f }
ServedAnswered { body: b } => fabric_storage_unwire_identity(text: b)
}
FabricStorageServed { endpoint: e } =>
match served_post(endpoint: e, operation: "identity", request: "") {
ServedFault { fault: f } => FabricIdentityReadRefused { fault: f }
Expand Down
Loading
Loading