@fungi.computer/mycelium 0.0.2 → 0.2.0

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.
Files changed (40) hide show
  1. package/README.md +70 -7
  2. package/dist/access.d.ts +2 -7
  3. package/dist/access.js +0 -3
  4. package/dist/execute-tool.d.ts +3 -2
  5. package/dist/execute-tool.js +40 -11
  6. package/dist/image-collector.d.ts +1 -1
  7. package/dist/index.d.ts +14 -1
  8. package/dist/index.js +2 -1
  9. package/dist/internal/build-identity.node.js +1 -1
  10. package/dist/internal/execution-lifecycle.d.ts +4 -2
  11. package/dist/internal/execution-lifecycle.js +97 -54
  12. package/dist/internal/host-cores.d.ts +2 -0
  13. package/dist/internal/host-cores.js +4 -0
  14. package/dist/internal/host-cores.node.d.ts +2 -0
  15. package/dist/internal/host-cores.node.js +5 -0
  16. package/dist/mcp-catalog.d.ts +0 -6
  17. package/dist/mcp-catalog.js +0 -1
  18. package/dist/mcp.d.ts +0 -1
  19. package/dist/mcp.js +0 -1
  20. package/dist/output-collector.d.ts +46 -0
  21. package/dist/output-collector.js +145 -0
  22. package/dist/runtime.js +1 -1
  23. package/dist/sandbox-admission.d.ts +19 -0
  24. package/dist/sandbox-admission.js +21 -0
  25. package/dist/sandbox-boundary.js +32 -23
  26. package/dist/sandbox-failure-event.d.ts +1 -1
  27. package/dist/sandbox-failure-event.js +1 -0
  28. package/dist/sandbox-failure.d.ts +12 -1
  29. package/dist/sandbox-failure.js +14 -0
  30. package/dist/sandbox-guest.d.ts +6 -6
  31. package/dist/sandbox-guest.js +5 -7
  32. package/dist/sandbox-wire.d.ts +5 -0
  33. package/dist/sandbox-wire.js +20 -1
  34. package/dist/source-runtime.js +3 -3
  35. package/docs/api/index.md +68 -5
  36. package/docs/api/mcp.md +0 -2
  37. package/docs/api/sandbox-failure.md +90 -0
  38. package/docs/api/sandbox-guest.md +36 -30
  39. package/docs/api/sandbox-wire.md +3 -3
  40. package/package.json +9 -5
@@ -1,6 +1,6 @@
1
1
  import { sandboxOperatorValue, sandboxGuestFailure, } from "./sandbox-boundary.js";
2
2
  import { z } from "zod";
3
- import { SourceInvalid, DeadlineExceeded, ResultNotJson, SandboxCrashed, BadResponse, DispatchLost, Cancelled, ResultTooLarge, CapabilityFailed, Unknown, } from "./sandbox-failure.js";
3
+ import { SourceInvalid, DeadlineExceeded, SandboxBusy, ResultNotJson, SandboxCrashed, BadResponse, DispatchLost, Cancelled, ResultTooLarge, CapabilityFailed, Unknown, } from "./sandbox-failure.js";
4
4
  /** The host-to-host result contract; raw diagnostic fields never go to guest code. */
5
5
  export const sandboxWireSchema = z.discriminatedUnion("ok", [
6
6
  z.strictObject({ ok: z.literal(true), value: z.json() }),
@@ -24,6 +24,12 @@ export const sandboxWireSchema = z.discriminatedUnion("ok", [
24
24
  limitMs: z.number().int().positive(),
25
25
  elapsedMs: z.number().nonnegative(),
26
26
  }),
27
+ z.strictObject({
28
+ kind: z.literal("sandbox_busy"),
29
+ code: z.literal("sandbox-busy"),
30
+ capacity: z.int().positive(),
31
+ waitedMs: z.number().nonnegative(),
32
+ }),
27
33
  z.strictObject({
28
34
  kind: z.literal("result_not_json"),
29
35
  valueKind: z.string().max(80),
@@ -82,6 +88,11 @@ export function sandboxWireFailure(error) {
82
88
  return sandboxGuestFailure(error);
83
89
  case "deadline_exceeded":
84
90
  return new DeadlineExceeded(error);
91
+ case "sandbox_busy":
92
+ return new SandboxBusy({
93
+ capacity: error.capacity,
94
+ waitedMs: error.waitedMs,
95
+ });
85
96
  case "result_not_json":
86
97
  return new ResultNotJson({
87
98
  kind: error.valueKind,
@@ -131,6 +142,14 @@ export function sandboxFailureWire(failure) {
131
142
  elapsedMs: failure.elapsedMs,
132
143
  };
133
144
  break;
145
+ case "SandboxBusy":
146
+ error = {
147
+ kind: "sandbox_busy",
148
+ code: failure.code,
149
+ capacity: failure.capacity,
150
+ waitedMs: failure.waitedMs,
151
+ };
152
+ break;
134
153
  case "Cancelled":
135
154
  error = { kind: "cancelled", by: failure.by };
136
155
  break;
@@ -9,11 +9,11 @@ function compareCodeUnits(left, right) {
9
9
  return left < right ? -1 : left > right ? 1 : 0;
10
10
  }
11
11
  const maximumCapabilitySources = 128;
12
- const sourceIdSchema = z.string().min(1).max(160);
13
- const sourceSnapshotSchema = z.object({
12
+ const sourceIdSchema = z.lazy(() => z.string().min(1).max(160));
13
+ const sourceSnapshotSchema = z.lazy(() => z.object({
14
14
  version: z.string().min(1).max(160),
15
15
  modules: z.array(z.unknown()),
16
- });
16
+ }));
17
17
  const maximumCandidateModules = 1_000;
18
18
  function validateSources(input) {
19
19
  if (input.length > maximumCapabilitySources) {
package/docs/api/index.md CHANGED
@@ -378,7 +378,6 @@ type AccessOptions = Readonly<{
378
378
  sessionGrants?: (context) => Grants;
379
379
  beforeCall?: (signal) => Promise<void>;
380
380
  confirmWrites?: boolean;
381
- approvedWrites?: (context) => readonly string[];
382
381
  confirm?: (request, signal) => Promise<boolean>;
383
382
  onRefused?: (refusal, context) => void;
384
383
  }>;
@@ -387,7 +386,8 @@ type AccessOptions = Readonly<{
387
386
  Host-supplied access data and the one way to ask a person. Every field is
388
387
  optional: hosted defaults allow unnamed modules, and no `confirm` means an
389
388
  operation requiring approval is refused, never run unasked. MCP catalogs
390
- explicitly default unnamed modules to none and require approval for writes.
389
+ explicitly default unnamed modules to none. Native hosts own durable approval
390
+ policy for admitted writes; explicit author confirmation still uses this port.
391
391
 
392
392
  ---
393
393
 
@@ -503,10 +503,11 @@ Closed failure vocabulary for the first Mycelium runtime slice.
503
503
  type ExecutionOptions = Readonly<{
504
504
  timeoutMs?: number;
505
505
  abortGraceMs?: number;
506
- }>;
506
+ }> &
507
+ SandboxAdmissionOptions;
507
508
  ```
508
509
 
509
- Host-selectable execution limits; neither budget can be disabled.
510
+ Host execution limits plus the reserved, host-only admission contract.
510
511
 
511
512
  ---
512
513
 
@@ -515,7 +516,7 @@ Host-selectable execution limits; neither budget can be disabled.
515
516
  ```ts
516
517
  type CollectedImage = Readonly<{
517
518
  data: string;
518
- mimeType: "image/jpeg" | "image/png" | "image/webp";
519
+ mimeType: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
519
520
  path: string;
520
521
  bytes: number;
521
522
  }>;
@@ -543,10 +544,14 @@ The collector as one execution's operations see it: push only.
543
544
  type InvocationContext = Readonly<{
544
545
  executionId: string;
545
546
  toolCallId?: string;
547
+ operationOrdinal?: number;
546
548
  toolCallCode?: string;
547
549
  deadlineAt: number | null;
548
550
  signal: AbortSignal;
549
551
  images?: ExecutionImages;
552
+ output?: Readonly<{
553
+ write: (stream, bytes) => void;
554
+ }>;
550
555
  }>;
551
556
  ```
552
557
 
@@ -835,6 +840,32 @@ Asked before every call of a gated module's operations.
835
840
 
836
841
  ---
837
842
 
843
+ ### SandboxAdmissionOptions
844
+
845
+ ```ts
846
+ type SandboxAdmissionOptions = Readonly<{
847
+ sandboxCapacity?: number;
848
+ admissionWaitMs?: number;
849
+ }>;
850
+ ```
851
+
852
+ Host-owned admission inputs; never part of guest execute arguments.
853
+
854
+ ---
855
+
856
+ ### SandboxAdmissionPolicy
857
+
858
+ ```ts
859
+ type SandboxAdmissionPolicy = Readonly<{
860
+ capacity: number;
861
+ waitMs: number;
862
+ }>;
863
+ ```
864
+
865
+ Captured once per runtime and shared across backing-work groups.
866
+
867
+ ---
868
+
838
869
  ### SandboxFailureEvent
839
870
 
840
871
  ```ts
@@ -925,6 +956,7 @@ const SandboxFailureEventSchema: Struct<{
925
956
  "SourceInvalid",
926
957
  "GuestThrew",
927
958
  "DeadlineExceeded",
959
+ "SandboxBusy",
928
960
  "Cancelled",
929
961
  "DispatchLost",
930
962
  "SandboxCrashed",
@@ -942,6 +974,31 @@ const SandboxFailureEventSchema: Struct<{
942
974
 
943
975
  Shared structural grammar for durable operator facts and client inspection.
944
976
 
977
+ ## Functions
978
+
979
+ ### normalizeSandboxAdmissionPolicy()
980
+
981
+ ```ts
982
+ function normalizeSandboxAdmissionPolicy(
983
+ options,
984
+ availableCores?,
985
+ ): SandboxAdmissionPolicy;
986
+ ```
987
+
988
+ Validate host policy and resolve defaults from a platform-owned core
989
+ observation.
990
+
991
+ #### Parameters
992
+
993
+ | Parameter | Type |
994
+ | ----------------- | ------------------------------------------------------------------------------------------------- |
995
+ | `options` | \| `Readonly`\<\{ `sandboxCapacity?`: `number`; `admissionWaitMs?`: `number`; \}\> \| `undefined` |
996
+ | `availableCores?` | `number` |
997
+
998
+ #### Returns
999
+
1000
+ [`SandboxAdmissionPolicy`](#sandboxadmissionpolicy)
1001
+
945
1002
  ## References
946
1003
 
947
1004
  ### sandboxFailure
@@ -1010,6 +1067,12 @@ Re-exports [DeadlineExceeded](sandbox-failure.md#deadlineexceeded)
1010
1067
 
1011
1068
  ---
1012
1069
 
1070
+ ### SandboxBusy
1071
+
1072
+ Re-exports [SandboxBusy](sandbox-failure.md#sandboxbusy)
1073
+
1074
+ ---
1075
+
1013
1076
  ### Cancelled
1014
1077
 
1015
1078
  Re-exports [Cancelled](sandbox-failure.md#cancelled)
package/docs/api/mcp.md CHANGED
@@ -44,7 +44,6 @@ type McpCatalogSnapshot = Readonly<{
44
44
  instructions: string;
45
45
  sources: readonly CapabilitySource[];
46
46
  grants: Grants;
47
- approvedWrites?: readonly string[];
48
47
  }>;
49
48
  ```
50
49
 
@@ -93,7 +92,6 @@ type McpExecutionContext = Readonly<{
93
92
  onPart?: (part) => Promise<void>;
94
93
  access: Pick<AccessOptions, "confirm"> &
95
94
  Readonly<{
96
- confirmWrites: true;
97
95
  beforeCall: (signal) => Promise<void>;
98
96
  }>;
99
97
  }>;
@@ -312,6 +312,95 @@ Data.TaggedError("DeadlineExceeded").acknowledged;
312
312
 
313
313
  ---
314
314
 
315
+ ### SandboxBusy
316
+
317
+ Admission expired before any sandbox work started.
318
+
319
+ #### Extends
320
+
321
+ - `YieldableError`\<`this`\> & `object` &
322
+ `Readonly`\<[`SandboxFailureReference`](#sandboxfailurereference) & `object`\>
323
+
324
+ #### Constructors
325
+
326
+ ##### Constructor
327
+
328
+ ```ts
329
+ new SandboxBusy(args): SandboxBusy;
330
+ ```
331
+
332
+ ###### Parameters
333
+
334
+ | Parameter | Type |
335
+ | --------------- | ------------------------------------------------------------------- |
336
+ | `args` | \{ `ref?`: `string`; `capacity`: `number`; `waitedMs`: `number`; \} |
337
+ | `args.ref?` | `string` |
338
+ | `args.capacity` | `number` |
339
+ | `args.waitedMs` | `number` |
340
+
341
+ ###### Returns
342
+
343
+ [`SandboxBusy`](#sandboxbusy)
344
+
345
+ ###### Inherited from
346
+
347
+ ```ts
348
+ Data.TaggedError("SandboxBusy")<
349
+ SandboxFailureReference & {
350
+ readonly capacity: number;
351
+ readonly waitedMs: number;
352
+ }
353
+ >.constructor
354
+ ```
355
+
356
+ #### Properties
357
+
358
+ ##### ref?
359
+
360
+ ```ts
361
+ readonly optional ref?: string;
362
+ ```
363
+
364
+ ###### Inherited from
365
+
366
+ ```ts
367
+ Data.TaggedError("SandboxBusy").ref;
368
+ ```
369
+
370
+ ##### capacity
371
+
372
+ ```ts
373
+ readonly capacity: number;
374
+ ```
375
+
376
+ ###### Inherited from
377
+
378
+ ```ts
379
+ Data.TaggedError("SandboxBusy").capacity;
380
+ ```
381
+
382
+ ##### waitedMs
383
+
384
+ ```ts
385
+ readonly waitedMs: number;
386
+ ```
387
+
388
+ ###### Inherited from
389
+
390
+ ```ts
391
+ Data.TaggedError("SandboxBusy").waitedMs;
392
+ ```
393
+
394
+ ##### code
395
+
396
+ ```ts
397
+ readonly code: "sandbox-busy" = "sandbox-busy";
398
+ ```
399
+
400
+ Stable contention code, not a sandbox health failure.
401
+
402
+ ---
403
+
315
404
  ### Cancelled
316
405
 
317
406
  The invocation owner accepted cancellation.
@@ -1078,6 +1167,7 @@ type SandboxFailure =
1078
1167
  | SourceInvalid
1079
1168
  | GuestThrew
1080
1169
  | DeadlineExceeded
1170
+ | SandboxBusy
1081
1171
  | Cancelled
1082
1172
  | DispatchLost
1083
1173
  | SandboxCrashed
@@ -13,32 +13,34 @@
13
13
  ### sandboxGuestResultSchema
14
14
 
15
15
  ```ts
16
- const sandboxGuestResultSchema: ZodDiscriminatedUnion<
17
- [
18
- ZodObject<
19
- {
20
- ok: ZodLiteral<true>;
21
- value: ZodUnknown;
22
- },
23
- $strict
24
- >,
25
- ZodObject<
26
- {
27
- ok: ZodLiteral<false>;
28
- error: ZodObject<
29
- {
30
- kind: ZodLiteral<"guest_threw">;
31
- name: ZodString;
32
- message: ZodString;
33
- transportMessage: ZodOptional<ZodString>;
34
- },
35
- $strict
36
- >;
37
- },
38
- $strict
39
- >,
40
- ],
41
- "ok"
16
+ const sandboxGuestResultSchema: ZodLazy<
17
+ ZodDiscriminatedUnion<
18
+ [
19
+ ZodObject<
20
+ {
21
+ ok: ZodLiteral<true>;
22
+ value: ZodUnknown;
23
+ },
24
+ $strict
25
+ >,
26
+ ZodObject<
27
+ {
28
+ ok: ZodLiteral<false>;
29
+ error: ZodObject<
30
+ {
31
+ kind: ZodLiteral<"guest_threw">;
32
+ name: ZodString;
33
+ message: ZodString;
34
+ transportMessage: ZodOptional<ZodString>;
35
+ },
36
+ $strict
37
+ >;
38
+ },
39
+ $strict
40
+ >,
41
+ ],
42
+ "ok"
43
+ >
42
44
  >;
43
45
  ```
44
46
 
@@ -49,7 +51,7 @@ Closed guest envelope: guest exceptions cannot masquerade as host failures.
49
51
  ### sandboxNamespaceSegmentSchema
50
52
 
51
53
  ```ts
52
- const sandboxNamespaceSegmentSchema: ZodString;
54
+ const sandboxNamespaceSegmentSchema: ZodLazy<ZodString>;
53
55
  ```
54
56
 
55
57
  Parsed guest namespace segments; callbacks never cross this wire.
@@ -59,7 +61,7 @@ Parsed guest namespace segments; callbacks never cross this wire.
59
61
  ### sandboxTransportAliasSchema
60
62
 
61
63
  ```ts
62
- const sandboxTransportAliasSchema: ZodString;
64
+ const sandboxTransportAliasSchema: ZodLazy<ZodString>;
63
65
  ```
64
66
 
65
67
  A transport alias is interpolated as a strict JavaScript binding identifier.
@@ -69,7 +71,9 @@ A transport alias is interpolated as a strict JavaScript binding identifier.
69
71
  ### sandboxNamespacePathsSchema
70
72
 
71
73
  ```ts
72
- const sandboxNamespacePathsSchema: ZodRecord<ZodString, ZodArray<ZodString>>;
74
+ const sandboxNamespacePathsSchema: ZodLazy<
75
+ ZodRecord<ZodLazy<ZodString>, ZodArray<ZodLazy<ZodString>>>
76
+ >;
73
77
  ```
74
78
 
75
79
  Transport aliases mapped to their logical namespace paths.
@@ -79,7 +83,9 @@ Transport aliases mapped to their logical namespace paths.
79
83
  ### sandboxBindingNamesSchema
80
84
 
81
85
  ```ts
82
- const sandboxBindingNamesSchema: ZodRecord<ZodString, ZodArray<ZodString>>;
86
+ const sandboxBindingNamesSchema: ZodLazy<
87
+ ZodRecord<ZodLazy<ZodString>, ZodArray<ZodString>>
88
+ >;
83
89
  ```
84
90
 
85
91
  Serializable flat transport table; operation keys may have any namespace depth.
@@ -88,9 +88,9 @@ Convert one validated wire failure into the shared error channel.
88
88
 
89
89
  #### Parameters
90
90
 
91
- | Parameter | Type |
92
- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
- | `error` | \| \{ `kind`: `"invalid_source"`; `line`: `number`; `column`: `number`; `excerpt`: `string`; \} \| \{ `kind`: `"guest_threw"`; `name`: `string`; `message`: `string`; `transportMessage?`: `string`; \} \| \{ `kind`: `"deadline_exceeded"`; `limitMs`: `number`; `elapsedMs`: `number`; \} \| \{ `kind`: `"result_not_json"`; `valueKind`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"sandbox_crashed"`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"bad_response"`; `reason`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"dispatch_lost"`; `elapsedMs`: `number`; `transport`: `string`; `errno?`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"cancelled"`; `by`: `"caller"` \| `"operator"`; \} \| \{ `kind`: `"result_too_large"`; `size`: `number`; \} \| \{ `kind`: `"capability_failed"`; `namespace`: `string`; `operation`: `string`; `cause`: \{ `kind`: `"Files"` \| `"Forage"` \| `"InvalidInput"` \| `"Unavailable"` \| `"OperationFailed"`; `message`: `string`; \}; `rawCause`: `JSONType`; \} \| \{ `kind`: `"unknown"`; `rawCause`: `JSONType`; \} |
91
+ | Parameter | Type |
92
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
+ | `error` | \| \{ `kind`: `"invalid_source"`; `line`: `number`; `column`: `number`; `excerpt`: `string`; \} \| \{ `kind`: `"guest_threw"`; `name`: `string`; `message`: `string`; `transportMessage?`: `string`; \} \| \{ `kind`: `"deadline_exceeded"`; `limitMs`: `number`; `elapsedMs`: `number`; \} \| \{ `kind`: `"sandbox_busy"`; `code`: `"sandbox-busy"`; `capacity`: `number`; `waitedMs`: `number`; \} \| \{ `kind`: `"result_not_json"`; `valueKind`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"sandbox_crashed"`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"bad_response"`; `reason`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"dispatch_lost"`; `elapsedMs`: `number`; `transport`: `string`; `errno?`: `string`; `rawCause`: `JSONType`; \} \| \{ `kind`: `"cancelled"`; `by`: `"caller"` \| `"operator"`; \} \| \{ `kind`: `"result_too_large"`; `size`: `number`; \} \| \{ `kind`: `"capability_failed"`; `namespace`: `string`; `operation`: `string`; `cause`: \{ `kind`: `"Files"` \| `"Forage"` \| `"InvalidInput"` \| `"Unavailable"` \| `"OperationFailed"`; `message`: `string`; \}; `rawCause`: `JSONType`; \} \| \{ `kind`: `"unknown"`; `rawCause`: `JSONType`; \} |
94
94
 
95
95
  #### Returns
96
96
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/mycelium",
3
- "version": "0.0.2",
3
+ "version": "0.2.0",
4
4
  "author": "Levi <levi@technomancy.dev>",
5
5
  "description": "Effect-native scoped capability lifecycle with a Zod-authored execute door",
6
6
  "type": "module",
@@ -61,6 +61,10 @@
61
61
  }
62
62
  },
63
63
  "imports": {
64
+ "#host-cores": {
65
+ "node": "./dist/internal/host-cores.node.js",
66
+ "default": "./dist/internal/host-cores.js"
67
+ },
64
68
  "#build-identity": {
65
69
  "node": "./dist/internal/build-identity.node.js",
66
70
  "default": "./dist/internal/build-identity.js"
@@ -74,10 +78,10 @@
74
78
  "THIRD_PARTY_NOTICES"
75
79
  ],
76
80
  "dependencies": {
77
- "@fungi.computer/cairn": "0.0.1",
78
- "@fungi.computer/forage": "0.0.2",
79
- "@fungi.computer/mule": "0.0.2",
80
- "@fungi.computer/puffball": "0.0.2",
81
+ "@fungi.computer/cairn": "0.1.0",
82
+ "@fungi.computer/forage": "0.2.0",
83
+ "@fungi.computer/mule": "0.1.0",
84
+ "@fungi.computer/puffball": "0.2.0",
81
85
  "effect": "4.0.2",
82
86
  "zod": "4.4.3",
83
87
  "acorn": "8.18.0",