From 0ddc953102a06424e9d731d60ace171dfcd19f06 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 29 Oct 2026 07:17:49 +0000 Subject: [PATCH] docs(chord): dependency model: placement required on remote types --- packages/chord/docs/next/dependencies/book.md | 24 ++++++-------- .../chord/docs/next/dependencies/index.html | 31 +++++++------------ .../chord/docs/next/dependencies/model.md | 12 +++---- 3 files changed, 24 insertions(+), 43 deletions(-) diff --git a/packages/chord/docs/next/dependencies/book.md b/packages/chord/docs/next/dependencies/book.md index 4d9a45678..15665a434 100644 --- a/packages/chord/docs/next/dependencies/book.md +++ b/packages/chord/docs/next/dependencies/book.md @@ -195,12 +195,10 @@ compares the consumer with the provider actually selected, never with a same-nam host (today `#assertRoute` does that before placement, so worker W1 serving `Notes` v1 rejects a `Notes` v2 request placed on W2, which serves v2). -One case keeps today's rule: a `remote` type declared **without placement** (allowed by `remote()`, used in tests and -for server types a tab reaches through its parent). It goes here if it is served here, otherwise over the parent. A -request of that kind made before the host has a parent link (a tab loads before it connects) waits here as not served -and is placed again when the host's first parent link connects (Opus, Sol); on a host that never connects, the root, -it stays here. Opus would rather require a placement on every remote type, which is simpler; it removes a supported -declaration, and the owner asked for no feature to go, so the draft keeps the fallback. +Every `remote` type declares its placement (owner, 2026-10-29). Until then `remote()` allowed leaving it out, a +leftover of slice 3a, which built remote objects over one link before host kinds existed; such a type went "here if +served, otherwise the parent", which needed its own fallback and a re-placement when a tab that loads before it +connects gets its first parent link (Opus, Sol). Opus and Fable proposed making it required; the owner agreed. ## What the check finds @@ -1218,7 +1216,7 @@ scenarios against five drafts; the catalog in the chapters before this one is a | R18, the boundary | "live" means every dependency was live at the end of activation | the dependency check is the boundary: after it, a dependency leaving `live` is treated as after live | | `self.get` of a missing `local` type | throws in the factory: `broken` | unbound `not_served`: `failed { waiting }`, woken by the publication that serves it | | a remote hold the provider cannot serve | refused `broken`; the dependent polls by backoff | refused and kept at the provider, re-run at its publication; `failed { waiting }` | -| design §3, placement | "served here" decides "here" | the address decides; a remote type without placement keeps today's rule | +| design §3, placement | "served here" decides "here"; `placement` optional on `remote()` | the address decides; every remote type declares its placement (owner, 2026-10-29) | | the start barrier, `pendingLoad` | holds wait for all of `load` | holds wait only for the publication; the barrier is (a) or (b) | | S2, a registry reader newer than its provider | `broken` | `failed { waiting, version }` | | S3, a registry without a value | `transient`, woken at the first value only | `failed { waiting }`, woken at every transition to usable | @@ -1318,12 +1316,9 @@ A needs W's B, B needs S's C; W's hold for C waits for S's whole `load`, which w holding host closes), never because its provider is missing, went away or does not fit. - **Placement by address** (round 1): a `local` type goes here; a `remote` type with a placement goes to the address its placement (computed from the consumer's own contract) gives: here if that is this host's address, whether served - here or not, else over the route for that kind or the parent (design §3). A `remote` type **without placement** keeps - today's rule (round 2: Fable, Opus, Astra; no feature removed): here if served here, otherwise over the parent. A - request of that kind made before the host has a parent link waits here `not_served` and is **re-placed when the - host's first parent link connects** (round 3: Opus N5, Sol 3: a tab loads before it connects); on a host that never - connects (the root), it stays here. Opus would rather require a placement on every `remote()`; that removes a - supported declaration, so the draft keeps the fallback. A hold arriving for an address that is not this host's is relayed or + here or not, else over the route for that kind or the parent (design §3). Every `remote` type declares + its placement (owner, 2026-10-29: the optional placement of slice 3a is removed, and with it the fallback "here if + served, otherwise the parent" and its re-placement at the first parent link). A hold arriving for an address that is not this host's is relayed or refused (`invalid/placement`) as today; a relay never captures a hold because it serves the same name. - **Then the selected provider is checked** (served, version or accepted version and fingerprint, `authorize`, the provider's own placement check). Version checks never look at a same-name registration elsewhere. @@ -1433,8 +1428,7 @@ through, or recovers by its own backoff. | Event | Re-evaluates | | --- | --- | | **a target changes state**: a dependency's object goes live, loading, fails, gets a new cause or ends; a hold's `bound`, `loading`, `failed` arrive, also after a re-hold on a new link | the requests bound to it, and their dependents (§3.4) | -| **a name becomes usable, an install ends, or the first parent link connects, on a host**: a publication (`load`'s setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) | the unbound requests indexed under those names; the provider's `installing` holds; at the first parent link, the -no-placement remote requests waiting here; a refused hold re-runs its start and sends `loading`, then `bound` or `failed` | +| **a name becomes usable, or an install ends, on a host**: a publication (`load`'s setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) | the unbound requests indexed under those names; the provider's `installing` holds; a refused hold re-runs its start and sends `loading`, then `bound` or `failed` | No new message kind for wakes: `loading`, `bound`, `failed` and `retry` exist. The wire's `failed` carries the new cause kind `waiting`; `loading` and a `waiting` `failed` carry the provider's attempt id for the probe (§7). diff --git a/packages/chord/docs/next/dependencies/index.html b/packages/chord/docs/next/dependencies/index.html index 3cbb8f533..656a4f6fa 100644 --- a/packages/chord/docs/next/dependencies/index.html +++ b/packages/chord/docs/next/dependencies/index.html @@ -327,12 +327,10 @@ address. A request placed here whose provider is missing is unbound here compares the consumer with the provider actually selected, never with a same-name registration on the consumer's own host (today #assertRoute does that before placement, so worker W1 serving Notes v1 rejects a Notes v2 request placed on W2, which serves v2).

-

One case keeps today's rule: a remote type declared without placement (allowed by remote(), used in tests and -for server types a tab reaches through its parent). It goes here if it is served here, otherwise over the parent. A -request of that kind made before the host has a parent link (a tab loads before it connects) waits here as not served -and is placed again when the host's first parent link connects (Opus, Sol); on a host that never connects, the root, -it stays here. Opus would rather require a placement on every remote type, which is simpler; it removes a supported -declaration, and the owner asked for no feature to go, so the draft keeps the fallback.

+

Every remote type declares its placement (owner, 2026-10-29). Until then remote() allowed leaving it out, a +leftover of slice 3a, which built remote objects over one link before host kinds existed; such a type went "here if +served, otherwise the parent", which needed its own fallback and a re-placement when a tab that loads before it +connects gets its first parent link (Opus, Sol). Opus and Fable proposed making it required; the owner agreed.

What the check finds

Once placed, the provider found there is checked: served, a fitting version (the current one or an accepted older one, with the fingerprint computed from the provider's own history), authorize, and the provider's own placement check. @@ -1932,8 +1930,8 @@ owner's decisions. design §3, placement -"served here" decides "here" -the address decides; a remote type without placement keeps today's rule +"served here" decides "here"; placement optional on remote() +the address decides; every remote type declares its placement (owner, 2026-10-29) the start barrier, pendingLoad @@ -2103,12 +2101,9 @@ holding host closes), never because its provider is missing, went away or does n

  • Placement by address (round 1): a local type goes here; a remote type with a placement goes to the address its placement (computed from the consumer's own contract) gives: here if that is this host's address, whether served -here or not, else over the route for that kind or the parent (design §3). A remote type without placement keeps -today's rule (round 2: Fable, Opus, Astra; no feature removed): here if served here, otherwise over the parent. A -request of that kind made before the host has a parent link waits here not_served and is re-placed when the -host's first parent link connects (round 3: Opus N5, Sol 3: a tab loads before it connects); on a host that never -connects (the root), it stays here. Opus would rather require a placement on every remote(); that removes a -supported declaration, so the draft keeps the fallback. A hold arriving for an address that is not this host's is relayed or +here or not, else over the route for that kind or the parent (design §3). Every remote type declares +its placement (owner, 2026-10-29: the optional placement of slice 3a is removed, and with it the fallback "here if +served, otherwise the parent" and its re-placement at the first parent link). A hold arriving for an address that is not this host's is relayed or refused (invalid/placement) as today; a relay never captures a hold because it serves the same name.

  • Then the selected provider is checked (served, version or accepted version and fingerprint, authorize, the @@ -2307,12 +2302,8 @@ unchanged dependency held only by this object must not end in between; today' the requests bound to it, and their dependents (§3.4) -a name becomes usable, an install ends, or the first parent link connects, on a host: a publication (load's setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) -the unbound requests indexed under those names; the provider's installing holds; at the first parent link, the - - -no-placement remote requests waiting here; a refused hold re-runs its start and sends loading, then bound or failed - +a name becomes usable, or an install ends, on a host: a publication (load's setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) +the unbound requests indexed under those names; the provider's installing holds; a refused hold re-runs its start and sends loading, then bound or failed

    No new message kind for wakes: loading, bound, failed and retry exist. The wire's failed carries the new cause diff --git a/packages/chord/docs/next/dependencies/model.md b/packages/chord/docs/next/dependencies/model.md index 172f2a688..2b838eb79 100644 --- a/packages/chord/docs/next/dependencies/model.md +++ b/packages/chord/docs/next/dependencies/model.md @@ -63,12 +63,9 @@ A needs W's B, B needs S's C; W's hold for C waits for S's whole `load`, which w holding host closes), never because its provider is missing, went away or does not fit. - **Placement by address** (round 1): a `local` type goes here; a `remote` type with a placement goes to the address its placement (computed from the consumer's own contract) gives: here if that is this host's address, whether served - here or not, else over the route for that kind or the parent (design §3). A `remote` type **without placement** keeps - today's rule (round 2: Fable, Opus, Astra; no feature removed): here if served here, otherwise over the parent. A - request of that kind made before the host has a parent link waits here `not_served` and is **re-placed when the - host's first parent link connects** (round 3: Opus N5, Sol 3: a tab loads before it connects); on a host that never - connects (the root), it stays here. Opus would rather require a placement on every `remote()`; that removes a - supported declaration, so the draft keeps the fallback. A hold arriving for an address that is not this host's is relayed or + here or not, else over the route for that kind or the parent (design §3). Every `remote` type declares + its placement (owner, 2026-10-29: the optional placement of slice 3a is removed, and with it the fallback "here if + served, otherwise the parent" and its re-placement at the first parent link). A hold arriving for an address that is not this host's is relayed or refused (`invalid/placement`) as today; a relay never captures a hold because it serves the same name. - **Then the selected provider is checked** (served, version or accepted version and fingerprint, `authorize`, the provider's own placement check). Version checks never look at a same-name registration elsewhere. @@ -178,8 +175,7 @@ through, or recovers by its own backoff. | Event | Re-evaluates | | --- | --- | | **a target changes state**: a dependency's object goes live, loading, fails, gets a new cause or ends; a hold's `bound`, `loading`, `failed` arrive, also after a re-hold on a new link | the requests bound to it, and their dependents (§3.4) | -| **a name becomes usable, an install ends, or the first parent link connects, on a host**: a publication (`load`'s setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) | the unbound requests indexed under those names; the provider's `installing` holds; at the first parent link, the -no-placement remote requests waiting here; a refused hold re-runs its start and sends `loading`, then `bound` or `failed` | +| **a name becomes usable, or an install ends, on a host**: a publication (`load`'s setups, a reload's commit, an install's commit) serves a type, a registry, a version; a registry composes or maps a value at a version; an install ends without a commit (rejected) | the unbound requests indexed under those names; the provider's `installing` holds; a refused hold re-runs its start and sends `loading`, then `bound` or `failed` | No new message kind for wakes: `loading`, `bound`, `failed` and `retry` exist. The wire's `failed` carries the new cause kind `waiting`; `loading` and a `waiting` `failed` carry the provider's attempt id for the probe (§7).