@fungi.computer/oyster 0.6.0 → 0.7.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 (163) hide show
  1. package/README.md +132 -78
  2. package/dist/agent-archive-projection.d.ts +8 -0
  3. package/dist/agent-archive-projection.js +49 -0
  4. package/dist/agent-schedules.d.ts +50 -0
  5. package/dist/agent-schedules.js +17 -0
  6. package/dist/agents.d.ts +35 -14
  7. package/dist/agents.js +93 -144
  8. package/dist/app-builds.d.ts +7 -2
  9. package/dist/app-builds.js +19 -2
  10. package/dist/approval-capability.d.ts +1 -1
  11. package/dist/approval-capability.js +11 -16
  12. package/dist/approval-home.d.ts +2 -1
  13. package/dist/approval-home.js +5 -3
  14. package/dist/apps/catalog.js +1 -1
  15. package/dist/apps/gate.d.ts +4 -7
  16. package/dist/apps/gate.js +14 -29
  17. package/dist/apps/index.d.ts +1 -1
  18. package/dist/apps/installation.d.ts +4 -42
  19. package/dist/apps/installation.js +7 -75
  20. package/dist/apps/operations.js +0 -10
  21. package/dist/apps/permissions.d.ts +18 -8
  22. package/dist/apps/permissions.js +7 -1
  23. package/dist/auth.d.ts +1 -24
  24. package/dist/auth.js +9 -39
  25. package/dist/authorization.d.ts +307 -0
  26. package/dist/authorization.js +542 -0
  27. package/dist/boot-host-script.js +1 -1
  28. package/dist/build/build-jobs.d.ts +2 -2
  29. package/dist/build/candidate-builder.d.ts +2 -0
  30. package/dist/build/candidate-builder.js +5 -1
  31. package/dist/build/candidate-cli.js +3 -0
  32. package/dist/build/candidate-cli.mjs +59 -21
  33. package/dist/build/job-log.d.ts +23 -0
  34. package/dist/build/job-log.js +88 -0
  35. package/dist/build/local-build.d.ts +2 -0
  36. package/dist/build/local-build.js +11 -9
  37. package/dist/cloudflare.d.ts +4 -1
  38. package/dist/cloudflare.js +1 -1
  39. package/dist/files.js +9 -8
  40. package/dist/git-admission.d.ts +3 -3
  41. package/dist/git-admission.js +4 -6
  42. package/dist/git-door.d.ts +8 -7
  43. package/dist/git-door.js +18 -17
  44. package/dist/git.d.ts +1 -1
  45. package/dist/host.d.ts +33 -40
  46. package/dist/host.js +153 -272
  47. package/dist/installation-execution.js +10 -5
  48. package/dist/installation-operations.d.ts +4 -180
  49. package/dist/installation-operations.js +1 -5
  50. package/dist/installation-store-generation.d.ts +4 -1
  51. package/dist/installation-store-generation.js +59 -6
  52. package/dist/internal/delivery.js +0 -1
  53. package/dist/internal/host-gate.d.ts +3 -2
  54. package/dist/internal/host-gate.js +5 -18
  55. package/dist/internal/invocation-timing.d.ts +16 -0
  56. package/dist/internal/invocation-timing.js +23 -0
  57. package/dist/internal/registry-installations.js +1 -0
  58. package/dist/invocation.d.ts +15 -14
  59. package/dist/invocation.js +58 -26
  60. package/dist/keys.d.ts +2 -19
  61. package/dist/keys.js +1 -37
  62. package/dist/mcp.d.ts +15 -27
  63. package/dist/mcp.js +105 -155
  64. package/dist/page/agent-browser.d.ts +15 -0
  65. package/dist/page/agent-browser.js +162 -0
  66. package/dist/page/app-permissions-port.d.ts +3 -0
  67. package/dist/page/app-permissions-port.js +43 -0
  68. package/dist/page/app-permissions.d.ts +11 -0
  69. package/dist/page/app-permissions.js +296 -0
  70. package/dist/page/isolated-page-theme.d.ts +2 -0
  71. package/dist/page/isolated-page-theme.js +11 -0
  72. package/dist/page/mount.d.ts +2 -13
  73. package/dist/page/mount.js +7 -93
  74. package/dist/page-script.d.ts +0 -3
  75. package/dist/page-script.js +3 -4
  76. package/dist/standalone/agent-archive-owner.d.ts +42 -0
  77. package/dist/standalone/agent-archive-owner.js +116 -0
  78. package/dist/standalone/agent-archive-schedules.d.ts +6 -0
  79. package/dist/standalone/agent-archive-schedules.js +76 -0
  80. package/dist/standalone/agent-archive.d.ts +31 -0
  81. package/dist/standalone/agent-archive.js +67 -0
  82. package/dist/standalone/agent-computers.d.ts +7 -6
  83. package/dist/standalone/agent-computers.js +4 -7
  84. package/dist/standalone/agent-mail.d.ts +2 -2
  85. package/dist/standalone/agents.d.ts +157 -20
  86. package/dist/standalone/agents.js +234 -30
  87. package/dist/standalone/app-builds-binding.js +1 -1
  88. package/dist/standalone/app-set.js +2 -54
  89. package/dist/standalone/app-source.d.ts +3 -4
  90. package/dist/standalone/app-source.js +12 -9
  91. package/dist/standalone/builds.d.ts +2 -14
  92. package/dist/standalone/builds.js +15 -13
  93. package/dist/standalone/computer-fleet.d.ts +4 -4
  94. package/dist/standalone/computer-fleet.js +13 -42
  95. package/dist/standalone/computer.d.ts +4 -3
  96. package/dist/standalone/computer.js +52 -53
  97. package/dist/standalone/dashboard-approval.d.ts +10 -0
  98. package/dist/standalone/dashboard-approval.js +66 -0
  99. package/dist/standalone/machine-link.d.ts +4 -221
  100. package/dist/standalone/machine-link.js +21 -15
  101. package/dist/standalone/media.d.ts +1 -0
  102. package/dist/standalone/media.js +20 -14
  103. package/dist/standalone/owner-routes.d.ts +16 -0
  104. package/dist/standalone/owner-routes.js +21 -0
  105. package/dist/standalone/permission-resources.d.ts +5 -0
  106. package/dist/standalone/permission-resources.js +31 -0
  107. package/dist/standalone/registry.d.ts +7 -0
  108. package/dist/standalone/registry.js +3 -0
  109. package/dist/standalone/tenancy.d.ts +0 -3
  110. package/dist/standalone/tenancy.js +2 -5
  111. package/dist/standalone/worker-routes.d.ts +19 -0
  112. package/dist/standalone/worker-routes.js +9 -0
  113. package/dist/standalone/worker.d.ts +1 -1
  114. package/dist/standalone/worker.js +27 -35
  115. package/dist/standalone/workflow-binding.d.ts +8 -3
  116. package/dist/standalone/workflow-binding.js +14 -5
  117. package/dist/standalone/workflow-git-capture.js +2 -1
  118. package/dist/standalone/workflow-host.d.ts +8 -103
  119. package/dist/standalone/workflow-host.js +1 -1
  120. package/dist/standalone/workflow-node-capture.js +2 -2
  121. package/dist/standalone/workflow-root-authority.d.ts +1 -1
  122. package/dist/standalone/workflow-root-authority.js +1 -1
  123. package/dist/standalone/workflow-schedules.d.ts +14 -5
  124. package/dist/standalone/workflow-schedules.js +11 -5
  125. package/dist/standalone/workflow-webhooks.d.ts +4 -18
  126. package/dist/standalone/workflow-webhooks.js +5 -5
  127. package/dist/standalone/workflows.d.ts +36 -28
  128. package/dist/standalone/workflows.js +6 -3
  129. package/dist/storage-frame.d.ts +6 -6
  130. package/dist/testing/capabilities.d.ts +7 -6
  131. package/dist/testing/capabilities.js +3 -6
  132. package/dist/testing/installation.d.ts +0 -1
  133. package/dist/testing/installation.js +2 -5
  134. package/dist/workers-git.d.ts +12 -4
  135. package/dist/workers-git.js +38 -35
  136. package/dist/workers.d.ts +9 -1
  137. package/dist/workers.js +44 -8
  138. package/dist/workflows.d.ts +2 -0
  139. package/dist/workflows.js +1 -0
  140. package/docs/api/README.md +7 -0
  141. package/docs/api/agent-schedules.md +175 -0
  142. package/docs/api/agents.md +34 -13
  143. package/docs/api/app-storage.md +1 -1
  144. package/docs/api/apps.md +323 -225
  145. package/docs/api/auth.md +0 -55
  146. package/docs/api/authorization.md +1300 -0
  147. package/docs/api/build.md +40 -37
  148. package/docs/api/cloudflare.md +3 -3
  149. package/docs/api/git.md +20 -11
  150. package/docs/api/host.md +64 -192
  151. package/docs/api/index.md +1 -1
  152. package/docs/api/invocation.md +14 -14
  153. package/docs/api/keys.md +1 -98
  154. package/docs/api/mcp.md +43 -40
  155. package/docs/api/modules.md +2 -0
  156. package/docs/api/page/mount.md +16 -19
  157. package/docs/api/workers-git.md +46 -12
  158. package/docs/api/workers.md +124 -235
  159. package/package.json +39 -20
  160. package/dist/page/computer-target.d.ts +0 -3
  161. package/dist/page/computer-target.js +0 -9
  162. package/dist/standalone/channel-session-door.d.ts +0 -4
  163. package/dist/standalone/channel-session-door.js +0 -72
@@ -31,6 +31,7 @@ type FrameBindingMethod<Result> = Readonly<{
31
31
  decodeArgs: (raw) => readonly unknown[];
32
32
  decodeResult: z.ZodType<Result>["parse"];
33
33
  requiredOperations: (args) => readonly string[];
34
+ requestedResource?: (args) => ResourceRef;
34
35
  }>;
35
36
  ```
36
37
 
@@ -459,8 +460,7 @@ function createCloudflareInvocationGate<Host, FacetClass>(
459
460
  ): InvocationGate<Host>;
460
461
  ```
461
462
 
462
- End the native App facet when live authority closes early, before the gate
463
- admits again.
463
+ Stop the shared native App facet at cohort drain or revocation.
464
464
 
465
465
  #### Type Parameters
466
466
 
@@ -517,7 +517,7 @@ Guest code gets only host gatekeeper bindings and no ambient outbound access.
517
517
  | `loader` | \| `Readonly`\<\{ `get`: (`id`, `configure`) => `Readonly`\<\{ `getDurableObjectClass`: (`exportName`) => `FacetClass`; \}\>; \}\> \| `undefined` | The Worker Loader binding; without it backend execution is unavailable. |
518
518
  | `resolve` | (`release`, `scope`) => `Effect`\<`Readonly`\<\{ `release`: `Release`; `digest`: `Sha256Digest`; `backend`: `DurableBackend`; \}\>, `Error`\> | Resolves a Release ID to its verified durable backend. |
519
519
  | `guestEnv` | (`frame`) => `object` | Mints loopbacks bound to the captured invocation frame. |
520
- | `bootUi` | (`release`) => `Promise`\< \| \{ `kind`: `"passed"`; \} \| \{ `kind`: `"failed"`; `code`: `"ui_mount_failed"`; `diagnostics?`: \{ `failedPredicate`: \| `"unexpected_candidate_request"` \| `"response_status"` \| `"request_failed"` \| `"page_error"` \| `"candidate_not_mounted"`; `errorName?`: \| `"TypeError"` \| `"RangeError"` \| `"SyntaxError"` \| `"AbortError"` \| `"TimeoutError"` \| `"Other"` \| `"Error"`; `finalUrlPath`: `string`; `consoleErrors`: `string`[]; `pageErrors`: `string`[]; `failedRequests`: `object`[]; `droppedCount`: `number`; \}; \} \| \{ `kind`: `"not_checked"`; `code`: \| `"boot_runner_unavailable"` \| `"boot_browser_binding_missing"` \| `"boot_clone_unavailable"` \| `"boot_timeout"` \| `"boot_cleanup_failed"` \| `"ui_check_not_run_on_host"`; \} \| `null`\> | Host-owned UI check, or `null` when this executor deliberately skips it (for example, after the signed host already checked). |
520
+ | `bootUi` | (`release`) => `Promise`\< \| \{ `kind`: `"passed"`; \} \| \{ `kind`: `"failed"`; `code`: `"ui_mount_failed"`; `diagnostics?`: \{ `failedPredicate`: \| `"unexpected_candidate_request"` \| `"response_status"` \| `"request_failed"` \| `"page_error"` \| `"candidate_not_mounted"`; `errorName?`: \| `"Error"` \| `"TypeError"` \| `"RangeError"` \| `"SyntaxError"` \| `"AbortError"` \| `"TimeoutError"` \| `"Other"`; `finalUrlPath`: `string`; `consoleErrors`: `string`[]; `pageErrors`: `string`[]; `failedRequests`: `object`[]; `droppedCount`: `number`; \}; \} \| \{ `kind`: `"not_checked"`; `code`: \| `"boot_runner_unavailable"` \| `"boot_browser_binding_missing"` \| `"boot_clone_unavailable"` \| `"boot_timeout"` \| `"boot_cleanup_failed"` \| `"ui_check_not_run_on_host"`; \} \| `null`\> | Host-owned UI check, or `null` when this executor deliberately skips it (for example, after the signed host already checked). |
521
521
  | `limits?` | `Partial`\<`Readonly`\<\{ `cpuMs`: `number`; `subRequests`: `number`; \}\>\> | Guest CPU and subrequest budgets; omitted fields use safe defaults. |
522
522
  | `onAbort?` | (`reason`) => `Promise`\<`void`\> | Close the host's existing invocation frame after its state is fenced. |
523
523
 
package/docs/api/git.md CHANGED
@@ -29,8 +29,7 @@ type GitGrants = Readonly<{
29
29
  }>;
30
30
  ```
31
31
 
32
- Live host authority, reopened before every provider call. Null is an anonymous
33
- reader.
32
+ Live host authority, reopened before every provider call.
34
33
 
35
34
  ---
36
35
 
@@ -129,7 +128,6 @@ type GitDoorHost = Readonly<{
129
128
  workflow?: WorkflowAttestation & object;
130
129
  }>
131
130
  | null>;
132
- isPublic: Promise<boolean>;
133
131
  git: Promise<
134
132
  | Readonly<{
135
133
  push: Promise<Readonly<{
@@ -152,6 +150,18 @@ Identity and selected installation come only from host-held ports.
152
150
 
153
151
  ---
154
152
 
153
+ ### GitDoor
154
+
155
+ ```ts
156
+ type GitDoor = Readonly<{
157
+ fetch: (request) => Promise<Response>;
158
+ }>;
159
+ ```
160
+
161
+ One smart-HTTP exchange's answer; the host declares the route it serves at.
162
+
163
+ ---
164
+
155
165
  ### GitPushJournalPorts
156
166
 
157
167
  ```ts
@@ -207,9 +217,9 @@ storage.
207
217
 
208
218
  #### Parameters
209
219
 
210
- | Parameter | Type |
211
- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
212
- | `ports` | `Readonly`\<\{ `currentInstallation`: `Promise`\< \| `Readonly`\<\{ `installationId`: `string`; `instanceId`: [`InstanceId`](index.md#instanceid) \| `null`; `appId`: `AppId`; `release`: \{ `releaseId`: `Schema.refine`\<`ReleaseId`, `Schema.String`\>; `appId`: `Schema.refine`\<`AppId`, `Schema.String`\>; `artifact`: `Schema.Struct`\<\{ `artifactRef`: `Schema.refine`\<`ArtifactRef`, `Schema.String`\>; `artifactDigest`: `Schema.refine`\<`Sha256Digest`, `Schema.String`\>; `provenance`: `Schema.Struct`\<\{ `sourceRevision`: ...; `sourceTreeDigest`: ...; `buildRecipeDigest`: ...; \}\>; \}\>; \}; `releasePin`: `"pinned"` \| `"floating"`; `authority`: \{ `authorityVersion`: `number`; `declaredOperationsDigest`: `Sha256Digest`; `approvedGrants`: readonly `Readonly`\<\{ `capability`: \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ...; `capabilityApproved`: `true`; `operations`: readonly ...[]; `resources`: ... \| ...; \}\>[]; `approval`: \| `Readonly`\<\{ `by`: ... \| ... \| ...; `at`: `number`; `authorityVersion`: `number`; \}\> \| `null`; \}; `status`: `"enabled"` \| `"disabled"` \| `"deleted"`; `visibility`: `"private"` \| `"public"`; `approvedAnonymousMethods`: readonly `Readonly`\<\{ `name`: `string`; `digest`: `Sha256Digest`; \}\>[]; `anonymousApproval`: \| `Readonly`\<\{ `by`: \| \{ `kind`: ...; `memberId`: ...; \} \| \{ `kind`: ...; `agentId`: ...; \} \| \{ `kind`: ...; `keyId`: ...; \}; `at`: `number`; `authorityVersion`: `number`; \}\> \| `null`; \}\> \| `null`\>; `declaration`: `Promise`\< \| `Readonly`\<\{ `api?`: `AppApi`; `displayName?`: `string`; `capabilities`: readonly `AppCapabilityId`[]; `calls?`: readonly `Readonly`\<\{ `appId`: ...; `methods`: ...; \}\>[]; `guidance?`: `string`; `handlers`: readonly `AppHandler`[]; `receives?`: readonly `"git.push"`[]; `icon?`: `string`; `roles`: readonly `AppRole`[]; `storage?`: readonly `AppStorageKey`[]; `commands?`: readonly `AppDeclaredCommand`[]; `gills?`: readonly `AppDeclaredGill`[]; `backend?`: `Readonly`\<\{ `bindings`: readonly ...[]; `sync?`: `Readonly`\<\{ `method`: ...; \}\>; \}\>; \}\> \| `null`\>; \}\> |
220
+ | Parameter | Type |
221
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
222
+ | `ports` | `Readonly`\<\{ `currentInstallation`: `Promise`\< \| `Readonly`\<\{ `installationId`: `string`; `instanceId`: [`InstanceId`](index.md#instanceid) \| `null`; `appId`: `AppId`; `release`: \{ `releaseId`: `Schema.refine`\<`ReleaseId`, `Schema.String`\>; `appId`: `Schema.refine`\<`AppId`, `Schema.String`\>; `artifact`: `Schema.Struct`\<\{ `artifactRef`: `Schema.refine`\<`ArtifactRef`, `Schema.String`\>; `artifactDigest`: `Schema.refine`\<`Sha256Digest`, `Schema.String`\>; `provenance`: `Schema.Struct`\<\{ `sourceRevision`: ...; `sourceTreeDigest`: ...; `buildRecipeDigest`: ...; \}\>; \}\>; \}; `releasePin`: `"pinned"` \| `"floating"`; `authority`: \{ `authorityVersion`: `number`; `declaredOperationsDigest`: `Sha256Digest`; `approvedGrants`: readonly `Readonly`\<\{ `capability`: \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ... \| ...; `capabilityApproved`: `true`; `operations`: readonly ...[]; `resources`: ... \| ...; \}\>[]; `approval`: \| `Readonly`\<\{ `by`: ... \| ... \| ...; `at`: `number`; `authorityVersion`: `number`; \}\> \| `null`; \}; `status`: `"enabled"` \| `"disabled"` \| `"deleted"`; \}\> \| `null`\>; `declaration`: `Promise`\< \| `Readonly`\<\{ `api?`: `AppApi`; `displayName?`: `string`; `capabilities`: readonly `AppCapabilityId`[]; `calls?`: readonly `Readonly`\<\{ `appId`: ...; `methods`: ...; \}\>[]; `guidance?`: `string`; `handlers`: readonly `AppHandler`[]; `receives?`: readonly `"git.push"`[]; `icon?`: `string`; `roles`: readonly `AppRole`[]; `storage?`: readonly `AppStorageKey`[]; `commands?`: readonly `AppDeclaredCommand`[]; `gills?`: readonly `AppDeclaredGill`[]; `backend?`: `Readonly`\<\{ `bindings`: readonly ...[]; `sync?`: `Readonly`\<\{ `method`: ...; \}\>; \}\>; \}\> \| `null`\>; \}\> |
213
223
 
214
224
  #### Returns
215
225
 
@@ -227,7 +237,7 @@ Reopen the host authority for this repository and requested scope.
227
237
 
228
238
  | Parameter | Type |
229
239
  | ------------ | --------------------- |
230
- | `writer` | `GitWriter` \| `null` |
240
+ | `writer` | `GitWriter` |
231
241
  | `repository` | `string` |
232
242
  | `scope` | `"read"` \| `"write"` |
233
243
 
@@ -328,11 +338,10 @@ null when it is not an exact Oyster Git exchange.
328
338
  ### createGitDoor()
329
339
 
330
340
  ```ts
331
- function createGitDoor(host): Hono;
341
+ function createGitDoor(host): GitDoor;
332
342
  ```
333
343
 
334
- Mount one smart-HTTP door with no provider credentials or alternate write
335
- branch.
344
+ One smart-HTTP door with no provider credentials or alternate write branch.
336
345
 
337
346
  #### Parameters
338
347
 
@@ -342,7 +351,7 @@ branch.
342
351
 
343
352
  #### Returns
344
353
 
345
- `Hono`
354
+ [`GitDoor`](#gitdoor)
346
355
 
347
356
  ---
348
357
 
package/docs/api/host.md CHANGED
@@ -98,32 +98,6 @@ A page descriptor carries routing, never the authority to use a capability.
98
98
 
99
99
  ---
100
100
 
101
- ### OysterVisitor
102
-
103
- ```ts
104
- type OysterVisitor = Readonly<{
105
- actor: Readonly<{
106
- kind: "visitor";
107
- }>;
108
- }>;
109
- ```
110
-
111
- The anonymous reader of a public installation. The host admits it only when
112
- authentication refuses; it reaches that App's page and its `read` methods.
113
-
114
- ---
115
-
116
- ### OysterPrincipal
117
-
118
- ```ts
119
- type OysterPrincipal = TenantPrincipal | OysterVisitor;
120
- ```
121
-
122
- Who an admitted request acts for: an authenticated tenant principal or the
123
- visitor.
124
-
125
- ---
126
-
127
101
  ### OysterAuthResult
128
102
 
129
103
  ```ts
@@ -181,6 +155,7 @@ type InstallationStore = InstallationReader &
181
155
  Readonly<{
182
156
  operations?: InstallationOperations;
183
157
  generation: () => Promise<string>;
158
+ resetAt?: () => Promise<number | null>;
184
159
  compareAndPut: (
185
160
  installation,
186
161
  expectedAuthorityVersion,
@@ -372,37 +347,21 @@ A capability adapter whose routes require live installation admission.
372
347
 
373
348
  ---
374
349
 
375
- ### OysterVariables
376
-
377
- ```ts
378
- type OysterVariables = TimingVariables & object;
379
- ```
380
-
381
- What the host stamps once per request; inner routes read it with `c.get`.
382
-
383
- #### Type Declaration
384
-
385
- | Name | Type |
386
- | --------------- | -------------------------------------- |
387
- | `principal` | [`OysterPrincipal`](#oysterprincipal) |
388
- | `installation?` | [`Installation`](apps.md#installation) |
389
-
390
- ---
391
-
392
350
  ### OysterEnv
393
351
 
394
352
  ```ts
395
353
  type OysterEnv = object;
396
354
  ```
397
355
 
398
- Owner routes run after the host's owner guard and read `c.get("principal")`.
356
+ The host table's Hono env; every route receives its principal from its declared
357
+ requirement.
399
358
 
400
359
  #### Properties
401
360
 
402
361
  ##### Variables
403
362
 
404
363
  ```ts
405
- Variables: OysterVariables;
364
+ Variables: TimingVariables;
406
365
  ```
407
366
 
408
367
  ---
@@ -463,6 +422,7 @@ type OysterHost = Readonly<{
463
422
  }
464
423
  | null>;
465
424
  computerControl?: (principal) => ComputerControlPort | null;
425
+ permissionResources?: (principal) => Promise<readonly ResourceOption[]>;
466
426
  auth: OysterAuth;
467
427
  backgroundOriginKey?: () => Promise<CryptoKey>;
468
428
  artifacts: ArtifactStore;
@@ -489,7 +449,7 @@ type OysterHost = Readonly<{
489
449
  guestLimits?: Partial<GuestLimits>;
490
450
  mcp?: OysterMcp;
491
451
  git?: OysterGitHost;
492
- ownerRoutes?: Hono<OysterEnv>;
452
+ ownerRoutes?: Routes<OysterEnv>;
493
453
  capabilities?: readonly OysterCapability[];
494
454
  workbench?: Readonly<{
495
455
  directory: Promise<Readonly<{
@@ -508,7 +468,6 @@ type OysterHost = Readonly<{
508
468
  pageScript?: string;
509
469
  pageAssets?: () => Promise<{
510
470
  pageScript: string;
511
- publicHomeScript: string;
512
471
  fontStyles: string;
513
472
  loginFontStyles: string;
514
473
  shellStyles: string;
@@ -522,6 +481,19 @@ Everything a host supplies to run Oyster.
522
481
 
523
482
  ---
524
483
 
484
+ ### OysterRouteTable
485
+
486
+ ```ts
487
+ type OysterRouteTable = Readonly<{
488
+ declarations: () => readonly RouteDeclaration[];
489
+ serve: () => ServedTable<OysterEnv>;
490
+ }>;
491
+ ```
492
+
493
+ One host's declared routes and the one way to serve them.
494
+
495
+ ---
496
+
525
497
  ### InstallationOperations
526
498
 
527
499
  ```ts
@@ -605,13 +577,13 @@ type InstallationOperations = Readonly<{
605
577
  | "request_failed"
606
578
  | "page_error"
607
579
  | "candidate_not_mounted";
608
- errorName?: | "TypeError"
580
+ errorName?: | "Error"
581
+ | "TypeError"
609
582
  | "RangeError"
610
583
  | "SyntaxError"
611
584
  | "AbortError"
612
585
  | "TimeoutError"
613
- | "Other"
614
- | "Error";
586
+ | "Other";
615
587
  finalUrlPath: string;
616
588
  consoleErrors: string[];
617
589
  pageErrors: string[];
@@ -660,17 +632,6 @@ type InstallationOperations = Readonly<{
660
632
  | null;
661
633
  };
662
634
  status: "enabled" | "disabled" | "deleted";
663
- visibility: "private" | "public";
664
- approvedAnonymousMethods: readonly Readonly<{
665
- name: string;
666
- digest: Sha256Digest;
667
- }>[];
668
- anonymousApproval: | Readonly<{
669
- by: ... | ... | ...;
670
- at: number;
671
- authorityVersion: number;
672
- }>
673
- | null;
674
635
  }
675
636
  | null;
676
637
  }
@@ -772,13 +733,13 @@ type InstallationOperations = Readonly<{
772
733
  | "request_failed"
773
734
  | "page_error"
774
735
  | "candidate_not_mounted";
775
- errorName?: | "TypeError"
736
+ errorName?: | "Error"
737
+ | "TypeError"
776
738
  | "RangeError"
777
739
  | "SyntaxError"
778
740
  | "AbortError"
779
741
  | "TimeoutError"
780
- | "Other"
781
- | "Error";
742
+ | "Other";
782
743
  finalUrlPath: string;
783
744
  consoleErrors: string[];
784
745
  pageErrors: string[];
@@ -827,17 +788,6 @@ type InstallationOperations = Readonly<{
827
788
  | null;
828
789
  };
829
790
  status: "enabled" | "disabled" | "deleted";
830
- visibility: "private" | "public";
831
- approvedAnonymousMethods: readonly Readonly<{
832
- name: string;
833
- digest: Sha256Digest;
834
- }>[];
835
- anonymousApproval: | Readonly<{
836
- by: ... | ... | ...;
837
- at: number;
838
- authorityVersion: number;
839
- }>
840
- | null;
841
791
  }
842
792
  | null;
843
793
  }
@@ -932,17 +882,6 @@ type InstallationOperations = Readonly<{
932
882
  | null;
933
883
  };
934
884
  status: "enabled" | "disabled" | "deleted";
935
- visibility: "private" | "public";
936
- approvedAnonymousMethods: readonly Readonly<{
937
- name: string;
938
- digest: Sha256Digest;
939
- }>[];
940
- anonymousApproval: | Readonly<{
941
- by: ... | ... | ...;
942
- at: number;
943
- authorityVersion: number;
944
- }>
945
- | null;
946
885
  }
947
886
  | null;
948
887
  acceptedAt: number;
@@ -969,17 +908,6 @@ type InstallationOperations = Readonly<{
969
908
  approval: Readonly<...> | null;
970
909
  };
971
910
  status: "enabled" | "disabled" | "deleted";
972
- visibility: "private" | "public";
973
- approvedAnonymousMethods: readonly Readonly<{
974
- name: ...;
975
- digest: ...;
976
- }>[];
977
- anonymousApproval: | Readonly<{
978
- by: ...;
979
- at: ...;
980
- authorityVersion: ...;
981
- }>
982
- | null;
983
911
  };
984
912
  hasBackend: boolean;
985
913
  prepared: boolean;
@@ -1134,28 +1062,6 @@ type InstallationOperations = Readonly<{
1134
1062
  | null;
1135
1063
  };
1136
1064
  status: "enabled" | "disabled" | "deleted";
1137
- visibility: "private" | "public";
1138
- approvedAnonymousMethods: readonly Readonly<{
1139
- name: string;
1140
- digest: Sha256Digest;
1141
- }>[];
1142
- anonymousApproval: | Readonly<{
1143
- by: | {
1144
- kind: ...;
1145
- memberId: ...;
1146
- }
1147
- | {
1148
- kind: ...;
1149
- agentId: ...;
1150
- }
1151
- | {
1152
- kind: ...;
1153
- keyId: ...;
1154
- };
1155
- at: number;
1156
- authorityVersion: number;
1157
- }>
1158
- | null;
1159
1065
  }
1160
1066
  | null;
1161
1067
  acceptedAt: number;
@@ -1192,17 +1098,6 @@ type InstallationOperations = Readonly<{
1192
1098
  | null;
1193
1099
  };
1194
1100
  status: "enabled" | "disabled" | "deleted";
1195
- visibility: "private" | "public";
1196
- approvedAnonymousMethods: readonly Readonly<{
1197
- name: string;
1198
- digest: Sha256Digest;
1199
- }>[];
1200
- anonymousApproval: | Readonly<{
1201
- by: ... | ... | ...;
1202
- at: number;
1203
- authorityVersion: number;
1204
- }>
1205
- | null;
1206
1101
  };
1207
1102
  hasBackend: boolean;
1208
1103
  prepared: boolean;
@@ -1430,53 +1325,6 @@ Default bounds for an App's UI asset build.
1430
1325
 
1431
1326
  ## Functions
1432
1327
 
1433
- ### oysterPrincipalIsVisitor()
1434
-
1435
- ```ts
1436
- function oysterPrincipalIsVisitor(
1437
- principal,
1438
- ): principal is Readonly<{ actor: Readonly<{ kind: "visitor" }> }>;
1439
- ```
1440
-
1441
- Narrow an admitted principal to the anonymous public reader.
1442
-
1443
- #### Parameters
1444
-
1445
- | Parameter | Type |
1446
- | ----------- | ------------------------------------- |
1447
- | `principal` | [`OysterPrincipal`](#oysterprincipal) |
1448
-
1449
- #### Returns
1450
-
1451
- `principal is Readonly<{ actor: Readonly<{ kind: "visitor" }> }>`
1452
-
1453
- ---
1454
-
1455
- ### oysterPrincipalIsOwner()
1456
-
1457
- ```ts
1458
- function oysterPrincipalIsOwner(
1459
- principal,
1460
- ): principal is Readonly<{
1461
- actor: { kind: "member"; memberId: string };
1462
- role: "owner";
1463
- }>;
1464
- ```
1465
-
1466
- True only for a member admitted with the owner role.
1467
-
1468
- #### Parameters
1469
-
1470
- | Parameter | Type |
1471
- | ----------- | ------------------------------------- |
1472
- | `principal` | [`OysterPrincipal`](#oysterprincipal) |
1473
-
1474
- #### Returns
1475
-
1476
- `principal is Readonly<{ actor: { kind: "member"; memberId: string }; role: "owner" }>`
1477
-
1478
- ---
1479
-
1480
1328
  ### oysterPrincipalId()
1481
1329
 
1482
1330
  ```ts
@@ -1521,9 +1369,9 @@ Completed selection, without re-deriving or executing outside Watchdog.
1521
1369
  | `host` | [`OysterHost`](#oysterhost) |
1522
1370
  | `installationId` | `string` |
1523
1371
  | `release` | `Release` |
1524
- | `principal` | [`OysterPrincipal`](#oysterprincipal) |
1372
+ | `principal` | [`TenantPrincipal`](tenant.md#tenantprincipal) |
1525
1373
  | `intent` | `"install-or-select"` \| `"install-or-remint"` \| `"create-only"` |
1526
- | `origin` | `"workflow"` \| `"owner-direct"` \| `"app"` |
1374
+ | `origin` | `"workflow"` \| `"app"` \| `"owner-direct"` |
1527
1375
  | `requestId` | `string` |
1528
1376
  | `signal` | `AbortSignal` |
1529
1377
 
@@ -1536,13 +1384,34 @@ Completed selection, without re-deriving or executing outside Watchdog.
1536
1384
  ### createOyster()
1537
1385
 
1538
1386
  ```ts
1539
- function createOyster(host): Hono<OysterEnv>;
1387
+ function createOyster(host): ServedTable<OysterEnv>;
1388
+ ```
1389
+
1390
+ Create the Oyster App server: a served route table that installs App Releases,
1391
+ serves their UI, forwards their backend requests and methods to their Instances,
1392
+ and mounts the host's MCP endpoint. The host's adapters decide where state lives
1393
+ and who may sign in.
1394
+
1395
+ #### Parameters
1396
+
1397
+ | Parameter | Type |
1398
+ | --------- | --------------------------- |
1399
+ | `host` | [`OysterHost`](#oysterhost) |
1400
+
1401
+ #### Returns
1402
+
1403
+ [`ServedTable`](authorization.md#servedtable)\<[`OysterEnv`](#oysterenv)\>
1404
+
1405
+ ---
1406
+
1407
+ ### oysterRouteTable()
1408
+
1409
+ ```ts
1410
+ function oysterRouteTable(host): OysterRouteTable;
1540
1411
  ```
1541
1412
 
1542
- Create the Oyster App server: a Hono app that installs App Releases, serves
1543
- their UI, forwards their backend requests and methods to their Instances, and
1544
- mounts the host's MCP endpoint. The host's adapters decide where state lives and
1545
- who may sign in.
1413
+ The Oyster host's declared route table: every route names its requirement
1414
+ (`authorization.ts`), so an undeclared route is never served.
1546
1415
 
1547
1416
  #### Parameters
1548
1417
 
@@ -1552,7 +1421,7 @@ who may sign in.
1552
1421
 
1553
1422
  #### Returns
1554
1423
 
1555
- `Hono`\<[`OysterEnv`](#oysterenv)\>
1424
+ [`OysterRouteTable`](#oysterroutetable)
1556
1425
 
1557
1426
  ---
1558
1427
 
@@ -1799,13 +1668,16 @@ function verifyRelease(
1799
1668
  api: | Readonly<{
1800
1669
  methods: Readonly<Record<string, Readonly<{
1801
1670
  description: string;
1802
- input: object;
1803
- output: object;
1671
+ input: {
1672
+ [key: ...]: ...;
1673
+ };
1674
+ output: {
1675
+ [key: ...]: ...;
1676
+ };
1804
1677
  effect: ... | ... | ...;
1805
1678
  requires: readonly ...;
1806
1679
  pending?: ... | ...;
1807
1680
  hidden?: ... | ...;
1808
- anonymous?: ... | ...;
1809
1681
  present?: ... | ...;
1810
1682
  }>>>;
1811
1683
  toolFamily?: Readonly<{
@@ -1999,10 +1871,10 @@ readonly `"git.push"`[]; `icon?`: `string`; `roles`: readonly (`"files"` \|
1999
1871
  `"application/vnd.fungi.app-backend+json"`; `artifactRef`: `ArtifactRef`;
2000
1872
  `digest`: `Sha256Digest`; `version`: `string`; `byteLength`: `number`; \}; \};
2001
1873
  `api`: \| `Readonly`\<\{ `methods`: `Readonly`\<`Record`\<`string`,
2002
- `Readonly`\<\{ `description`: `string`; `input`: `object`; `output`: `object`;
2003
- `effect`: ... \| ... \| ...; `requires`: readonly ...; `pending?`: ... \| ...;
2004
- `hidden?`: ... \| ...; `anonymous?`: ... \| ...; `present?`: ... \| ...;
2005
- \}\>\>\>; `toolFamily?`: `Readonly`\<\{ `name`: `string`; `list`: `string`;
1874
+ `Readonly`\<\{ `description`: `string`; `input`: \{ \[`key`: ...\]: ...; \};
1875
+ `output`: \{ \[`key`: ...\]: ...; \}; `effect`: ... \| ... \| ...; `requires`:
1876
+ readonly ...; `pending?`: ... \| ...; `hidden?`: ... \| ...; `present?`: ... \|
1877
+ ...; \}\>\>\>; `toolFamily?`: `Readonly`\<\{ `name`: `string`; `list`: `string`;
2006
1878
  `call`: `string`; \}\>; `events?`: `Readonly`\<`Record`\<`string`,
2007
1879
  `Readonly`\<\{ `description`: ...; `payload`: ...; \}\>\>\>; \}\> \| `null`;
2008
1880
  `declaration`: \| `Readonly`\<\{ `api?`: `Readonly`\<\{ `methods`:
package/docs/api/index.md CHANGED
@@ -448,13 +448,13 @@ const uiBootCheckOutcomeSchema: ZodDiscriminatedUnion<[ZodObject<{
448
448
  candidate_not_mounted: "candidate_not_mounted";
449
449
  }>;
450
450
  errorName: ZodOptional<ZodEnum<{
451
+ Error: "Error";
451
452
  TypeError: "TypeError";
452
453
  RangeError: "RangeError";
453
454
  SyntaxError: "SyntaxError";
454
455
  AbortError: "AbortError";
455
456
  TimeoutError: "TimeoutError";
456
457
  Other: "Other";
457
- Error: "Error";
458
458
  }>>;
459
459
  finalUrlPath: ZodString;
460
460
  consoleErrors: ZodArray<ZodPipe<ZodPipe<ZodString, ZodTransform<..., ...>>, ZodString>>;
@@ -107,7 +107,7 @@ type InvocationGatePorts<Host> = Readonly<{
107
107
  }>;
108
108
  ```
109
109
 
110
- The host's native guest-abort and authority-close hooks.
110
+ The host's native guest-abort and frame-authority-close hooks.
111
111
 
112
112
  #### Type Parameters
113
113
 
@@ -412,12 +412,13 @@ only its decision.
412
412
  function createInvocationGate<Host>(ports): InvocationGate<Host>;
413
413
  ```
414
414
 
415
- Admit frames against one guest. Verified foreground reads share it, up to eight
416
- at once; writes, raw backend requests, Gills and replay run alone. Every guest
417
- binding packet names its frame, so a finished frame's leftover timers cannot
418
- borrow a later frame's authority and a normal finish keeps the guest warm.
419
- Closing authority early (revocation, expiry, a write preempting replay) aborts
420
- the guest and so every frame sharing it; replay only yields to a verified write.
415
+ One Instance shares up to eight verified foreground reads; all other work runs
416
+ alone in first-come order. Every finish fences its frame; the last live frame
417
+ stops the native guest before closing authority and releasing admission. Binding
418
+ checks alone cannot stop a timer mutating the facet's own SQLite. Revocation,
419
+ expiry and a verified write preempting replay stop every live frame. Arrivals
420
+ wait for a stopping guest. Once the opening deadline passes, new reads queue
421
+ exclusively so the current cohort cannot be prolonged forever.
421
422
 
422
423
  #### Type Parameters
423
424
 
@@ -444,16 +445,15 @@ function invocationCallerContext(principal, computerId): object;
444
445
  ```
445
446
 
446
447
  Project an admitted principal into App attribution; only the host chooses the
447
- fixed Computer context. The App caller grammar has no visitor actor, so the
448
- anonymous public reader is attributed as the reserved `visitor` key without a
449
- Computer. Host admission reads the principal, never this projection.
448
+ fixed Computer context. Host admission reads the principal, never this
449
+ projection.
450
450
 
451
451
  #### Parameters
452
452
 
453
- | Parameter | Type |
454
- | ------------ | -------------------------------------------- |
455
- | `principal` | [`OysterPrincipal`](host.md#oysterprincipal) |
456
- | `computerId` | `string` \| `null` |
453
+ | Parameter | Type |
454
+ | ------------ | ---------------------------------------------- |
455
+ | `principal` | [`TenantPrincipal`](tenant.md#tenantprincipal) |
456
+ | `computerId` | `string` \| `null` |
457
457
 
458
458
  #### Returns
459
459