@volter/world-core 3.0.118 → 3.0.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/attach.cjs CHANGED
@@ -35,6 +35,8 @@ if (ref) {
35
35
  throw new Error(`[twin-attach] could not fetch the world manifest from ${url}: ${(probe.stderr || '').trim()}`);
36
36
  }
37
37
  const manifest = JSON.parse(probe.stdout);
38
+ const { worldAttachmentNetworkEnv, worldStrictEgress } = require('./network-policy.cjs');
39
+ Object.assign(process.env, worldAttachmentNetworkEnv(ref, manifest.network, process.env, worldStrictEgress(manifest.env ?? {})));
38
40
  // a served World's twins as loopback listeners that add its key (./http-bridge.cjs), so a client with its own HTTP
39
41
  // stack (wrangler's undici, which neither patch reaches) reaches them as it would a local World's: the twin URLs and
40
42
  // every endpoint variable naming a twin's place point at the listener. Ports are chosen by a blocking child, the
package/dist/attach.cjs CHANGED
@@ -35,6 +35,8 @@ if (ref) {
35
35
  throw new Error(`[twin-attach] could not fetch the world manifest from ${url}: ${(probe.stderr || '').trim()}`);
36
36
  }
37
37
  const manifest = JSON.parse(probe.stdout);
38
+ const { worldAttachmentNetworkEnv, worldStrictEgress } = require('./network-policy.cjs');
39
+ Object.assign(process.env, worldAttachmentNetworkEnv(ref, manifest.network, process.env, worldStrictEgress(manifest.env ?? {})));
38
40
  // a served World's twins as loopback listeners that add its key (./http-bridge.cjs), so a client with its own HTTP
39
41
  // stack (wrangler's undici, which neither patch reaches) reaches them as it would a local World's: the twin URLs and
40
42
  // every endpoint variable naming a twin's place point at the listener. Ports are chosen by a blocking child, the
@@ -171,6 +171,27 @@ function intersectWorldNetwork(own, ceiling) {
171
171
  return normalizeWorldNetwork({ egress, writes, phase: left.phase, passthrough, publicReads, ownLoopback });
172
172
  }
173
173
 
174
+ /** A remote attachment changes its World reference while retaining the caller's network ceiling. */
175
+ function worldAttachmentNetworkEnv(world, own, caller = {}, sourceStrict = false) {
176
+ let network = own === undefined ? undefined : normalizeWorldNetwork(own);
177
+ const serialized = caller[WORLD_NETWORK_POLICY_ENV];
178
+ if (serialized !== undefined) {
179
+ let ceiling;
180
+ try {
181
+ const { version, world: parent, ...permission } = parseWorldNetworkPolicy(JSON.parse(serialized));
182
+ ceiling = permission;
183
+ } catch { ceiling = { egress: [] }; }
184
+ network = network === undefined ? ceiling : intersectWorldNetwork(network, ceiling);
185
+ }
186
+ const strict = sourceStrict || worldStrictEgress(caller);
187
+ if (strict) network = network === undefined ? { egress: [] } : intersectWorldNetwork(network, { egress: [] });
188
+ return {
189
+ VOLTER_WORLD: world,
190
+ ...(network === undefined ? {} : { [WORLD_NETWORK_POLICY_ENV]: JSON.stringify(createWorldNetworkPolicy(world, network)) }),
191
+ ...(strict ? { VOLTER_TWIN_STRICT_EGRESS: '1' } : {}),
192
+ };
193
+ }
194
+
174
195
  /** Loopback and private addresses stay inside the machine a World runs on: never refused. */
175
196
  function isWorldInternalHost(hostname) {
176
197
  const h = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, '');
@@ -201,4 +222,4 @@ function worldEgressRefusal(value, env = process.env, method = 'GET') {
201
222
  return answer.outcome === 'refuse' ? `${answer.reason} (${refusalSide(answer)})` : null;
202
223
  }
203
224
 
204
- module.exports = { worldStrictEgress, worldGrantFromEnv, PUBLIC_BUILD_READS, READ_METHODS, intersectWorldNetwork, worldNetworkNeedsPathInspection, worldNetworkUsesPassthrough, isWorldInternalHost, worldEgressRefusal, WORLD_NETWORK_POLICY_ENV, normalizeWorldNetwork, createWorldNetworkPolicy, parseWorldNetworkPolicy, worldNetworkPolicyFromEnv, allowsWorldNetworkEgress };
225
+ module.exports = { worldAttachmentNetworkEnv, worldStrictEgress, worldGrantFromEnv, PUBLIC_BUILD_READS, READ_METHODS, intersectWorldNetwork, worldNetworkNeedsPathInspection, worldNetworkUsesPassthrough, isWorldInternalHost, worldEgressRefusal, WORLD_NETWORK_POLICY_ENV, normalizeWorldNetwork, createWorldNetworkPolicy, parseWorldNetworkPolicy, worldNetworkPolicyFromEnv, allowsWorldNetworkEgress };
@@ -15,3 +15,4 @@ export function worldEgressRefusal(value: string | URL, env?: Readonly<Record<st
15
15
  export function worldNetworkNeedsPathInspection(policy: WorldNetworkPolicy, value: string | URL): boolean;
16
16
  export function worldNetworkUsesPassthrough(policy: WorldNetworkPolicy, value: string | URL): boolean;
17
17
  export function intersectWorldNetwork(own: WorldNetwork, ceiling: WorldNetwork): WorldNetwork;
18
+ export function worldAttachmentNetworkEnv(world: string, own: WorldNetwork | undefined, caller?: Readonly<Record<string, string | undefined>>, sourceStrict?: boolean): Record<string, string>;
@@ -171,6 +171,27 @@ function intersectWorldNetwork(own, ceiling) {
171
171
  return normalizeWorldNetwork({ egress, writes, phase: left.phase, passthrough, publicReads, ownLoopback });
172
172
  }
173
173
 
174
+ /** A remote attachment changes its World reference while retaining the caller's network ceiling. */
175
+ function worldAttachmentNetworkEnv(world, own, caller = {}, sourceStrict = false) {
176
+ let network = own === undefined ? undefined : normalizeWorldNetwork(own);
177
+ const serialized = caller[WORLD_NETWORK_POLICY_ENV];
178
+ if (serialized !== undefined) {
179
+ let ceiling;
180
+ try {
181
+ const { version, world: parent, ...permission } = parseWorldNetworkPolicy(JSON.parse(serialized));
182
+ ceiling = permission;
183
+ } catch { ceiling = { egress: [] }; }
184
+ network = network === undefined ? ceiling : intersectWorldNetwork(network, ceiling);
185
+ }
186
+ const strict = sourceStrict || worldStrictEgress(caller);
187
+ if (strict) network = network === undefined ? { egress: [] } : intersectWorldNetwork(network, { egress: [] });
188
+ return {
189
+ VOLTER_WORLD: world,
190
+ ...(network === undefined ? {} : { [WORLD_NETWORK_POLICY_ENV]: JSON.stringify(createWorldNetworkPolicy(world, network)) }),
191
+ ...(strict ? { VOLTER_TWIN_STRICT_EGRESS: '1' } : {}),
192
+ };
193
+ }
194
+
174
195
  /** Loopback and private addresses stay inside the machine a World runs on: never refused. */
175
196
  function isWorldInternalHost(hostname) {
176
197
  const h = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, '');
@@ -201,4 +222,4 @@ function worldEgressRefusal(value, env = process.env, method = 'GET') {
201
222
  return answer.outcome === 'refuse' ? `${answer.reason} (${refusalSide(answer)})` : null;
202
223
  }
203
224
 
204
- module.exports = { worldStrictEgress, worldGrantFromEnv, PUBLIC_BUILD_READS, READ_METHODS, intersectWorldNetwork, worldNetworkNeedsPathInspection, worldNetworkUsesPassthrough, isWorldInternalHost, worldEgressRefusal, WORLD_NETWORK_POLICY_ENV, normalizeWorldNetwork, createWorldNetworkPolicy, parseWorldNetworkPolicy, worldNetworkPolicyFromEnv, allowsWorldNetworkEgress };
225
+ module.exports = { worldAttachmentNetworkEnv, worldStrictEgress, worldGrantFromEnv, PUBLIC_BUILD_READS, READ_METHODS, intersectWorldNetwork, worldNetworkNeedsPathInspection, worldNetworkUsesPassthrough, isWorldInternalHost, worldEgressRefusal, WORLD_NETWORK_POLICY_ENV, normalizeWorldNetwork, createWorldNetworkPolicy, parseWorldNetworkPolicy, worldNetworkPolicyFromEnv, allowsWorldNetworkEgress };
@@ -15,3 +15,4 @@ export function worldEgressRefusal(value: string | URL, env?: Readonly<Record<st
15
15
  export function worldNetworkNeedsPathInspection(policy: WorldNetworkPolicy, value: string | URL): boolean;
16
16
  export function worldNetworkUsesPassthrough(policy: WorldNetworkPolicy, value: string | URL): boolean;
17
17
  export function intersectWorldNetwork(own: WorldNetwork, ceiling: WorldNetwork): WorldNetwork;
18
+ export function worldAttachmentNetworkEnv(world: string, own: WorldNetwork | undefined, caller?: Readonly<Record<string, string | undefined>>, sourceStrict?: boolean): Record<string, string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/world-core",
3
- "version": "3.0.118",
3
+ "version": "3.0.120",
4
4
  "description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
5
5
  "keywords": [
6
6
  "twin",