@fungi.computer/oyster 0.2.0 → 0.3.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 (287) hide show
  1. package/README.md +376 -72
  2. package/dist/agents.d.ts +3 -2
  3. package/dist/agents.js +4 -2
  4. package/dist/app-builds.d.ts +81 -8
  5. package/dist/app-builds.js +210 -60
  6. package/dist/app-storage.d.ts +3 -3
  7. package/dist/approval-capability.d.ts +5 -0
  8. package/dist/approval-capability.js +46 -0
  9. package/dist/approval-home.d.ts +51 -0
  10. package/dist/approval-home.js +226 -0
  11. package/dist/apps/catalog.d.ts +335 -0
  12. package/dist/apps/catalog.js +46 -0
  13. package/dist/apps/gate.d.ts +20 -6
  14. package/dist/apps/gate.js +42 -16
  15. package/dist/apps/index.d.ts +3 -1
  16. package/dist/apps/index.js +3 -1
  17. package/dist/apps/installation.d.ts +132 -51
  18. package/dist/apps/installation.js +176 -70
  19. package/dist/apps/permissions.d.ts +247 -0
  20. package/dist/apps/permissions.js +255 -0
  21. package/dist/boot-capability-route.d.ts +15 -0
  22. package/dist/boot-capability-route.js +196 -0
  23. package/dist/boot-capability.d.ts +103 -0
  24. package/dist/boot-capability.js +141 -0
  25. package/dist/boot-construction.d.ts +12 -0
  26. package/dist/boot-construction.js +175 -0
  27. package/dist/boot-gate.d.ts +267 -0
  28. package/dist/boot-gate.js +236 -0
  29. package/dist/boot-host-script.d.ts +2 -0
  30. package/dist/boot-host-script.js +1 -0
  31. package/dist/boot-mount.d.ts +21 -0
  32. package/dist/boot-mount.js +65 -0
  33. package/dist/browser/boot.d.ts +73 -0
  34. package/dist/browser/boot.js +502 -0
  35. package/dist/browser/browser.d.ts +104 -0
  36. package/dist/browser/browser.js +374 -0
  37. package/dist/browser/capability-source.d.ts +76 -0
  38. package/dist/browser/capability-source.js +338 -0
  39. package/dist/browser/cdp-client.d.ts +56 -0
  40. package/dist/browser/cdp-client.js +184 -0
  41. package/dist/browser/errors.d.ts +79 -0
  42. package/dist/browser/errors.js +32 -0
  43. package/dist/browser/index.d.ts +16 -0
  44. package/dist/browser/index.js +14 -0
  45. package/dist/browser/lease-registry.d.ts +61 -0
  46. package/dist/browser/lease-registry.js +101 -0
  47. package/dist/browser/operations.d.ts +225 -0
  48. package/dist/browser/operations.js +137 -0
  49. package/dist/browser/page.d.ts +25 -0
  50. package/dist/browser/page.js +172 -0
  51. package/dist/browser/quick-reads.d.ts +29 -0
  52. package/dist/browser/quick-reads.js +160 -0
  53. package/dist/browser/sessions.d.ts +52 -0
  54. package/dist/browser/sessions.js +118 -0
  55. package/dist/browser/url-policy.d.ts +18 -0
  56. package/dist/browser/url-policy.js +58 -0
  57. package/dist/build/app-imports.d.ts +12 -0
  58. package/dist/build/app-imports.js +105 -0
  59. package/dist/build/build-policy.d.ts +5 -3
  60. package/dist/build/build-policy.js +5 -3
  61. package/dist/build/candidate-builder.d.ts +1 -1
  62. package/dist/build/candidate-cli.mjs +8375 -334
  63. package/dist/build/local-build.d.ts +2 -0
  64. package/dist/build/local-build.js +28 -6
  65. package/dist/build/snapshot-package-store.d.ts +1 -1
  66. package/dist/build/snapshot-package-store.js +7 -2
  67. package/dist/build/workspace-build.d.ts +92 -5
  68. package/dist/build/workspace-build.js +93 -19
  69. package/dist/build.d.ts +1 -1
  70. package/dist/build.js +1 -1
  71. package/dist/catalog-frame.js +1 -1
  72. package/dist/cloudflare.d.ts +13 -3
  73. package/dist/cloudflare.js +102 -4
  74. package/dist/frame-binding-wire-script.js +1 -1
  75. package/dist/frame-binding-wire.js +4 -2
  76. package/dist/git-auth.d.ts +0 -2
  77. package/dist/git-auth.js +0 -2
  78. package/dist/git.d.ts +0 -1
  79. package/dist/git.js +0 -2
  80. package/dist/host.d.ts +39 -13
  81. package/dist/host.js +268 -142
  82. package/dist/index.d.ts +25 -15
  83. package/dist/index.js +39 -16
  84. package/dist/install-release-cli.d.ts +2 -0
  85. package/dist/install-release-cli.js +46 -0
  86. package/dist/installation-client.d.ts +43 -0
  87. package/dist/installation-client.js +178 -0
  88. package/dist/installation-execution.d.ts +11 -0
  89. package/dist/installation-execution.js +184 -0
  90. package/dist/installation-operations.d.ts +1437 -0
  91. package/dist/installation-operations.js +664 -0
  92. package/dist/installation-store-generation.d.ts +3 -0
  93. package/dist/installation-store-generation.js +16 -0
  94. package/dist/instance-id.d.ts +10 -0
  95. package/dist/instance-id.js +10 -0
  96. package/dist/instance-refusal.d.ts +11 -0
  97. package/dist/instance-refusal.js +21 -0
  98. package/dist/internal/delivery.js +4 -2
  99. package/dist/internal/host-gate.js +7 -1
  100. package/dist/internal/registry-installations.js +4 -4
  101. package/dist/keys.d.ts +5 -1
  102. package/dist/keys.js +10 -2
  103. package/dist/machine-link/authority.d.ts +89 -0
  104. package/dist/machine-link/authority.js +37 -0
  105. package/dist/machine-link/client.d.ts +66 -0
  106. package/dist/machine-link/client.js +94 -0
  107. package/dist/machine-link/delivery.d.ts +18 -0
  108. package/dist/machine-link/delivery.js +55 -0
  109. package/dist/machine-link/enrollment.d.ts +111 -0
  110. package/dist/machine-link/enrollment.js +286 -0
  111. package/dist/machine-link/fences.d.ts +37 -0
  112. package/dist/machine-link/fences.js +166 -0
  113. package/dist/machine-link/home.d.ts +20 -0
  114. package/dist/machine-link/home.js +24 -0
  115. package/dist/machine-link/host.d.ts +43 -0
  116. package/dist/machine-link/host.js +189 -0
  117. package/dist/machine-link/index.d.ts +15 -0
  118. package/dist/machine-link/index.js +15 -0
  119. package/dist/machine-link/link.d.ts +48 -0
  120. package/dist/machine-link/link.js +223 -0
  121. package/dist/machine-link/presence.d.ts +10 -0
  122. package/dist/machine-link/presence.js +25 -0
  123. package/dist/machine-link/workers.d.ts +6 -0
  124. package/dist/machine-link/workers.js +6 -0
  125. package/dist/mcp-owner.d.ts +2 -2
  126. package/dist/mcp-owner.js +41 -33
  127. package/dist/mcp.d.ts +15 -3
  128. package/dist/mcp.js +146 -25
  129. package/dist/pack.d.ts +14 -3
  130. package/dist/pack.js +44 -19
  131. package/dist/page/app-access.d.ts +7 -0
  132. package/dist/page/app-access.js +75 -0
  133. package/dist/page/boot-host.js +57 -0
  134. package/dist/page/capabilities.d.ts +3 -3
  135. package/dist/page/capabilities.js +16 -12
  136. package/dist/page/computer-handles.d.ts +3 -3
  137. package/dist/page/computer-target.d.ts +3 -0
  138. package/dist/page/computer-target.js +9 -0
  139. package/dist/page/mount.d.ts +23 -3
  140. package/dist/page/mount.js +152 -16
  141. package/dist/page-assets.d.ts +22 -0
  142. package/dist/page-assets.js +28 -0
  143. package/dist/page-script.d.ts +3 -0
  144. package/dist/page-script.js +5 -4
  145. package/dist/release.d.ts +13 -6
  146. package/dist/release.js +10 -7
  147. package/dist/root-data.d.ts +16 -6
  148. package/dist/root-data.js +2 -2
  149. package/dist/source/index.d.ts +1 -1
  150. package/dist/source/team-source.d.ts +20 -8
  151. package/dist/source/team-source.js +39 -10
  152. package/dist/source/template-seed.d.ts +2 -2
  153. package/dist/standalone/agent-mail.d.ts +24 -0
  154. package/dist/standalone/agent-mail.js +62 -0
  155. package/dist/standalone/agent-store.d.ts +9 -0
  156. package/dist/standalone/agent-store.js +30 -0
  157. package/dist/standalone/agents.d.ts +68 -9
  158. package/dist/standalone/agents.js +428 -56
  159. package/dist/standalone/app-builds-binding.d.ts +20 -2
  160. package/dist/standalone/app-builds-binding.js +147 -23
  161. package/dist/standalone/app-set.d.ts +5 -2
  162. package/dist/standalone/app-set.js +174 -143
  163. package/dist/standalone/browser.d.ts +11 -0
  164. package/dist/standalone/browser.js +72 -0
  165. package/dist/standalone/builds.d.ts +13 -4
  166. package/dist/standalone/builds.js +28 -44
  167. package/dist/standalone/computer-egress.d.ts +2 -0
  168. package/dist/standalone/computer-egress.js +13 -4
  169. package/dist/standalone/computer-fleet.d.ts +43 -0
  170. package/dist/standalone/computer-fleet.js +200 -0
  171. package/dist/standalone/computer.d.ts +44 -9
  172. package/dist/standalone/computer.js +129 -22
  173. package/dist/standalone/install-apps-cli.js +43 -6
  174. package/dist/standalone/instance.d.ts +2 -2
  175. package/dist/standalone/instance.js +8 -11
  176. package/dist/standalone/machine-link.d.ts +354 -0
  177. package/dist/standalone/machine-link.js +368 -0
  178. package/dist/standalone/media.d.ts +2 -2
  179. package/dist/standalone/media.js +19 -16
  180. package/dist/standalone/preview.d.ts +2 -2
  181. package/dist/standalone/preview.js +37 -10
  182. package/dist/standalone/registry.d.ts +149 -9
  183. package/dist/standalone/registry.js +299 -8
  184. package/dist/standalone/worker.d.ts +19 -5
  185. package/dist/standalone/worker.js +90 -54
  186. package/dist/standalone/workflow-binding.d.ts +18 -22
  187. package/dist/standalone/workflow-binding.js +18 -18
  188. package/dist/standalone/workflow-control.d.ts +4 -0
  189. package/dist/standalone/workflow-control.js +40 -0
  190. package/dist/standalone/workflow-events.d.ts +2 -2
  191. package/dist/standalone/workflow-events.js +9 -10
  192. package/dist/standalone/workflow-git-capture.js +4 -3
  193. package/dist/standalone/workflow-host.d.ts +162 -161
  194. package/dist/standalone/workflow-host.js +101 -21
  195. package/dist/standalone/workflow-node-capture.js +11 -4
  196. package/dist/standalone/workflow-schedules.d.ts +5 -2
  197. package/dist/standalone/workflow-schedules.js +9 -10
  198. package/dist/standalone/workflow-trigger-host.d.ts +65 -5
  199. package/dist/standalone/workflow-trigger-host.js +2 -2
  200. package/dist/standalone/workflow-webhooks.d.ts +22 -0
  201. package/dist/standalone/workflow-webhooks.js +39 -0
  202. package/dist/standalone/workflows.d.ts +140 -43
  203. package/dist/standalone/workflows.js +198 -39
  204. package/dist/storage-frame.d.ts +6 -6
  205. package/dist/testing/capabilities.js +14 -3
  206. package/dist/testing/installation.js +26 -2
  207. package/dist/testing/worker.js +1 -1
  208. package/dist/testing/workers-runtime.d.ts +8 -2
  209. package/dist/testing/workers-runtime.js +20 -2
  210. package/dist/webhook-abuse.d.ts +25 -0
  211. package/dist/webhook-abuse.js +54 -0
  212. package/dist/webhook-custody.d.ts +144 -0
  213. package/dist/webhook-custody.js +222 -0
  214. package/dist/webhook-ingress.d.ts +36 -0
  215. package/dist/webhook-ingress.js +146 -0
  216. package/dist/webhooks.d.ts +111 -0
  217. package/dist/webhooks.js +189 -0
  218. package/dist/workers-git.d.ts +12 -17
  219. package/dist/workers-git.js +60 -52
  220. package/dist/workers.d.ts +224 -13
  221. package/dist/workers.js +351 -51
  222. package/dist/workflow-agent-authority.d.ts +8 -0
  223. package/dist/workflow-agent-authority.js +42 -0
  224. package/dist/workflows.d.ts +66 -0
  225. package/dist/workflows.js +97 -0
  226. package/docs/api/README.md +63 -37
  227. package/docs/api/agents.md +17 -0
  228. package/docs/api/app-storage.md +1 -1
  229. package/docs/api/apps.md +1394 -543
  230. package/docs/api/browser/boot.md +132 -0
  231. package/docs/api/browser.md +1440 -0
  232. package/docs/api/build-contract.md +38 -25
  233. package/docs/api/build.md +263 -84
  234. package/docs/api/cloudflare.md +93 -7
  235. package/docs/api/git.md +3 -13
  236. package/docs/api/host.md +944 -118
  237. package/docs/api/index.md +320 -18
  238. package/docs/api/keys.md +24 -1
  239. package/docs/api/mcp.md +59 -12
  240. package/docs/api/modules.md +33 -40
  241. package/docs/api/pack.md +57 -8
  242. package/docs/api/page/mount.md +92 -4
  243. package/docs/api/workers-git.md +103 -24
  244. package/docs/api/workers.md +1581 -244
  245. package/docs/site/agent-quickstart.mdx +28 -14
  246. package/examples/standalone/worker.ts +3 -1
  247. package/examples/standalone/wrangler.jsonc +2 -0
  248. package/package.json +73 -71
  249. package/dist/installation-consent.d.ts +0 -81
  250. package/dist/installation-consent.js +0 -84
  251. package/dist/shell/app-directory.d.ts +0 -542
  252. package/dist/shell/app-directory.js +0 -196
  253. package/dist/shell/browser-actions.d.ts +0 -7
  254. package/dist/shell/browser-actions.js +0 -56
  255. package/dist/shell/command-host.d.ts +0 -112
  256. package/dist/shell/command-host.js +0 -502
  257. package/dist/shell/commands.d.ts +0 -25
  258. package/dist/shell/commands.js +0 -78
  259. package/dist/shell/index.d.ts +0 -8
  260. package/dist/shell/index.js +0 -8
  261. package/dist/shell/keys.d.ts +0 -41
  262. package/dist/shell/keys.js +0 -134
  263. package/dist/shell/shell-module.d.ts +0 -55
  264. package/dist/shell/shell-module.js +0 -86
  265. package/dist/shell/window-manager.d.ts +0 -128
  266. package/dist/shell/window-manager.js +0 -730
  267. package/dist/shell/workbench-contract.d.ts +0 -68
  268. package/dist/shell/workbench-directory.d.ts +0 -332
  269. package/dist/shell/workbench-directory.js +0 -35
  270. package/dist/shell/workbench-host-types.d.ts +0 -96
  271. package/dist/shell/workbench-host-types.js +0 -1
  272. package/dist/shell/workbench-host.d.ts +0 -34
  273. package/dist/shell/workbench-host.js +0 -352
  274. package/dist/shell/workbench-model.d.ts +0 -194
  275. package/dist/shell/workbench-model.js +0 -53
  276. package/dist/shell/workbench.d.ts +0 -4
  277. package/dist/shell/workbench.js +0 -2
  278. package/docs/api/shell/app-directory.md +0 -599
  279. package/docs/api/shell/command-host.md +0 -224
  280. package/docs/api/shell/commands.md +0 -197
  281. package/docs/api/shell/keys.md +0 -183
  282. package/docs/api/shell/shell-module.md +0 -204
  283. package/docs/api/shell/window-manager.md +0 -267
  284. package/docs/api/shell/workbench-directory.md +0 -119
  285. package/docs/api/shell/workbench.md +0 -205
  286. package/docs/api/shell.md +0 -1915
  287. /package/dist/{shell/workbench-contract.js → page/boot-host.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import * as z from "zod";
2
2
  import { type AppApi, type AppDeclaration, type HostActor } from "@fungi.computer/puffball/app";
3
3
  import { type AppToolAccess } from "./tools.js";
4
- import { type DeclaredOperations, type Installation, type ApprovedGrant } from "./installation.js";
4
+ import { type ResourceRef, type DeclaredOperations, type Installation, type ApprovedGrant } from "./installation.js";
5
5
  /** Attested by the host, never authenticated by decoding request JSON. */
6
6
  export type HostPrincipal = Readonly<{
7
7
  actor: HostActor | Readonly<{
@@ -15,14 +15,26 @@ export declare const gateRequestSchema: z.ZodLazy<z.ZodDiscriminatedUnion<[z.Zod
15
15
  name: z.ZodString;
16
16
  input: z.ZodUnknown;
17
17
  via: z.ZodEnum<{
18
- ui: "ui";
19
18
  agent: "agent";
20
19
  mcp: "mcp";
20
+ ui: "ui";
21
21
  workflow: "workflow";
22
22
  }>;
23
+ resource: z.ZodOptional<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
24
+ kind: z.ZodString;
25
+ id: z.ZodString;
26
+ }, z.core.$strict>>>>;
27
+ }, z.core.$strict>, z.ZodObject<{
28
+ kind: z.ZodLiteral<"capability">;
29
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
30
+ operation: z.ZodOptional<z.ZodString>;
31
+ resource: z.ZodUnion<readonly [z.ZodLazy<z.ZodReadonly<z.ZodObject<{
32
+ kind: z.ZodString;
33
+ id: z.ZodString;
34
+ }, z.core.$strict>>>, z.ZodLiteral<"any">]>;
23
35
  }, z.core.$strict>, z.ZodObject<{
24
36
  kind: z.ZodLiteral<"capability-route">;
25
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
37
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
26
38
  operation: z.ZodString;
27
39
  }, z.core.$strict>, z.ZodObject<{
28
40
  kind: z.ZodLiteral<"binding">;
@@ -38,7 +50,9 @@ export type GateRequest = z.output<typeof gateRequestSchema>;
38
50
  /** Immutable values the host already read; resource/grantor freshness remains host-owned. */
39
51
  export type GateFacts = Readonly<{
40
52
  principal: HostPrincipal;
41
- installation: Installation;
53
+ installation: Readonly<Pick<Installation, "status" | "visibility" | "instanceId" | "authority"> & {
54
+ artifactDigest: string;
55
+ }>;
42
56
  declaration: AppDeclaration;
43
57
  declaredOperations: DeclaredOperations;
44
58
  api: AppApi | null;
@@ -79,10 +93,10 @@ export type GateDecision = Readonly<{
79
93
  method?: AppMethodDeclaration;
80
94
  }> | z.output<typeof gateRefusalSchema>;
81
95
  /** Intersect stored approvals with the current verified Release without widening resource selectors. */
82
- export declare function grantsFor(installation: Installation, declaration: AppDeclaration, snapshot: DeclaredOperations, capability: ApprovedGrant["capability"]): ApprovedGrant | null;
96
+ export declare function grantsFor(installation: Pick<GateFacts["installation"], "status" | "authority" | "artifactDigest">, declaration: AppDeclaration, snapshot: DeclaredOperations, capability: ApprovedGrant["capability"], resource?: ResourceRef | "any"): ApprovedGrant | null;
83
97
  /** Approved binding operations from an already verified declaration. Hosts still pin
84
98
  * the selection/version/artifact and compare running frame grants as a subset. */
85
- export declare function approvedBindingGrants(installation: Installation, declaration: AppDeclaration): InvocationGrants;
99
+ export declare function approvedBindingGrants(installation: Pick<GateFacts["installation"], "status" | "authority">, declaration: AppDeclaration): InvocationGrants;
86
100
  /** Narrow captured binding operations to the method's verified requirements and effect.
87
101
  * The captured set is the ceiling; this never adds an operation or resource authority. */
88
102
  export declare function scopedBindings(captured: InvocationGrants, method?: AppMethodDeclaration, ceiling?: "read" | "write"): InvocationGrants;
package/dist/apps/gate.js CHANGED
@@ -5,7 +5,7 @@ import * as z from "zod";
5
5
  import * as Schema from "effect/Schema";
6
6
  import { appBackendBindingKinds, appBackendBindingOperation, scopeOperationToMethod, appApiMethodNameSchema, appBackendBindingsSchema, appCapabilityIdSchema, } from "@fungi.computer/puffball/app";
7
7
  import { appToolAccessSchema } from "./tools.js";
8
- import { ownerCodec, } from "./installation.js";
8
+ import { ownerCodec, resourceRefSchema, } from "./installation.js";
9
9
  const bindingNameSchema = ownerCodec(Schema.Literals(Object.values(appBackendBindingKinds).map((kind) => kind.name)));
10
10
  /** Requests select existing SDK methods, opaque backend calls and derived operation identities. */
11
11
  export const gateRequestSchema = z.lazy(() => z.discriminatedUnion("kind", [
@@ -14,6 +14,13 @@ export const gateRequestSchema = z.lazy(() => z.discriminatedUnion("kind", [
14
14
  name: z.string(),
15
15
  input: z.unknown(),
16
16
  via: z.enum(["ui", "agent", "mcp", "workflow"]),
17
+ resource: resourceRefSchema.optional(),
18
+ }),
19
+ z.strictObject({
20
+ kind: z.literal("capability"),
21
+ capability: ownerCodec(appCapabilityIdSchema),
22
+ operation: z.string().min(1).optional(),
23
+ resource: z.union([resourceRefSchema, z.literal("any")]),
17
24
  }),
18
25
  z.strictObject({
19
26
  kind: z.literal("capability-route"),
@@ -55,17 +62,20 @@ export const gateRefusalSchema = z.lazy(() => z.strictObject({
55
62
  ]),
56
63
  }));
57
64
  /** Intersect stored approvals with the current verified Release without widening resource selectors. */
58
- export function grantsFor(installation, declaration, snapshot, capability) {
65
+ export function grantsFor(installation, declaration, snapshot, capability, resource = "any") {
59
66
  if (installation.status !== "enabled" ||
60
- snapshot.digest !== installation.declaredOperationsDigest ||
61
- snapshot.artifactDigest !== installation.release.artifact.artifactDigest ||
67
+ snapshot.digest !== installation.authority.declaredOperationsDigest ||
68
+ snapshot.artifactDigest !== installation.artifactDigest ||
62
69
  !declaration.capabilities.includes(capability))
63
70
  return null;
64
- const approved = installation.approvedGrants.find((grant) => grant.capability === capability);
71
+ const approved = installation.authority.approvedGrants.find((grant) => grant.capability === capability);
65
72
  const declared = snapshot.capabilities.find((row) => row.capability === capability)
66
73
  ?.operations ?? [];
67
74
  if (!approved?.capabilityApproved ||
68
- (approved.resources !== "tenant-scope" && approved.resources.length === 0))
75
+ (approved.resources !== "tenant-scope" &&
76
+ (resource === "any"
77
+ ? approved.resources.length === 0
78
+ : !approved.resources.some((ref) => ref.kind === resource.kind && ref.id === resource.id))))
69
79
  return null;
70
80
  const operations = approved.operations.filter((operation) => declared.includes(operation));
71
81
  return { ...approved, operations };
@@ -82,7 +92,7 @@ export function approvedBindingGrants(installation, declaration) {
82
92
  return (operation !== undefined &&
83
93
  operation.requires.length > 0 &&
84
94
  operation.requires.every((capability) => {
85
- const approved = installation.approvedGrants.find((grant) => grant.capability === capability);
95
+ const approved = installation.authority.approvedGrants.find((grant) => grant.capability === capability);
86
96
  return (declaration.capabilities.includes(capability) &&
87
97
  approved?.capabilityApproved &&
88
98
  (approved.resources === "tenant-scope" ||
@@ -128,13 +138,13 @@ function admissionRefusal(facts) {
128
138
  if (installation.status !== "enabled" ||
129
139
  (visitor && installation.visibility !== "public"))
130
140
  return refusal("unavailable");
131
- if (facts.declaredOperations.digest !== installation.declaredOperationsDigest ||
132
- facts.declaredOperations.artifactDigest !==
133
- installation.release.artifact.artifactDigest ||
141
+ if (facts.declaredOperations.digest !==
142
+ installation.authority.declaredOperationsDigest ||
143
+ facts.declaredOperations.artifactDigest !== installation.artifactDigest ||
134
144
  (facts.pins !== undefined &&
135
- (facts.pins.authorityVersion !== installation.authorityVersion ||
136
- facts.pins.artifactDigest !==
137
- installation.release.artifact.artifactDigest)))
145
+ (facts.pins.authorityVersion !==
146
+ installation.authority.authorityVersion ||
147
+ facts.pins.artifactDigest !== installation.artifactDigest)))
138
148
  return refusal("stale_authority");
139
149
  if ((principal.actor.kind === "agent" || principal.actor.kind === "team-key") &&
140
150
  !Schema.is(appToolAccessSchema)(facts.access))
@@ -161,9 +171,9 @@ function methodMetadata(facts, name) {
161
171
  return refusal("level_too_low");
162
172
  return { kind: "admitted", method };
163
173
  }
164
- function methodGrantRefusal(facts, method) {
174
+ function methodGrantRefusal(facts, method, resource = "any") {
165
175
  const { installation } = facts;
166
- if (method.requires.some((capability) => grantsFor(installation, facts.declaration, facts.declaredOperations, capability) === null))
176
+ if (method.requires.some((capability) => grantsFor(installation, facts.declaration, facts.declaredOperations, capability, resource) === null))
167
177
  return refusal("requires_not_granted");
168
178
  return null;
169
179
  }
@@ -221,7 +231,7 @@ export function admits(facts, rawRequest) {
221
231
  catch {
222
232
  return refusal("invalid_input");
223
233
  }
224
- const grantDenied = methodGrantRefusal(facts, method);
234
+ const grantDenied = methodGrantRefusal(facts, method, request.resource);
225
235
  if (grantDenied !== null)
226
236
  return grantDenied;
227
237
  return {
@@ -230,6 +240,22 @@ export function admits(facts, rawRequest) {
230
240
  method,
231
241
  };
232
242
  }
243
+ case "capability": {
244
+ if (visitor)
245
+ return refusal("visitor_read_only");
246
+ if (!facts.declaration.capabilities.includes(request.capability) ||
247
+ (request.operation !== undefined &&
248
+ facts.declaredOperations.capabilities
249
+ .find((row) => row.capability === request.capability)
250
+ ?.operations.includes(request.operation) !== true))
251
+ return refusal("not_declared");
252
+ const grant = grantsFor(installation, facts.declaration, facts.declaredOperations, request.capability, request.resource);
253
+ if (grant === null ||
254
+ (request.operation !== undefined &&
255
+ !grant.operations.includes(request.operation)))
256
+ return refusal("not_approved");
257
+ return { kind: "admitted", grants: [] };
258
+ }
233
259
  case "capability-route": {
234
260
  if (visitor)
235
261
  return refusal("visitor_read_only");
@@ -1,5 +1,7 @@
1
1
  /** Installation records and pure admission rules; tenant state and commits stay host-owned. */
2
- export { applyInstallationCommand, approvedGrantSchema, declaredOperationsSchema, installationCommandSchema, installationIdSchema, installationRefusalSchema, installationSchema, type Approval, type ApprovedGrant, type CapabilityOperationDescriptor, type DeclaredOperations, type GrantRequest, type Installation, type InstallationCommand, type InstallationContext, type InstallationReader, type InstallationRefusal, type InstallationUpdate, type ResourceRef, } from "./installation.js";
2
+ export { applyGrantCommand, appAuthoritySchema, grantCommandSchema, type AppAuthority, type GrantCommand, type GrantContext, type GrantRefusal, applyInstallationCommand, approvedGrantSchema, declaredOperationsSchema, installationCommandSchema, installationIdSchema, installationRefusalSchema, installationSchema, type Approval, type ApprovedGrant, type CapabilityOperationDescriptor, type DeclaredOperations, grantChangeSchema, type GrantChange, type Installation, type InstallationCommand, type InstallationContext, type InstallationReader, type InstallationRefusal, type InstallationUpdate, type ResourceRef, } from "./installation.js";
3
+ export { permissionPinsSchema, permissionSaveSchema, type PermissionPins, appPermissionsWireSchema, appPermissionPageSchema, permissionScreen, draftOf, editPermissions, planGrantChange, rebaseDraft, type PermissionDraft, type PermissionEdit, type PermissionScreen, type AppPermissionsWire, grantRequestFor, pendingCapabilities, type GrantRequestDecision, type ResourceOption, } from "./permissions.js";
3
4
  export { admits, admitMethodMetadata, appInvocationCeiling, approvedBindingGrants, scopedBindings, grantsFor, gateRefusalSchema, gateRequestSchema, invocationGrantsSchema, type AppMethodDeclaration, type AppMethodMetadataDecision, type GateDecision, type GateFacts, type GateRequest, type HostPrincipal, type InvocationGrants, } from "./gate.js";
4
5
  export { deriveDeclaredOperations, appCallOperation } from "./operations.js";
5
6
  export { appToolPolicySchema, type AppToolAccess, type AppToolEntry, type AppToolPolicy, } from "./tools.js";
7
+ export { permissionCatalog, type PermissionCatalogEntry } from "./catalog.js";
@@ -1,5 +1,7 @@
1
1
  /** Installation records and pure admission rules; tenant state and commits stay host-owned. */
2
- export { applyInstallationCommand, approvedGrantSchema, declaredOperationsSchema, installationCommandSchema, installationIdSchema, installationRefusalSchema, installationSchema, } from "./installation.js";
2
+ export { applyGrantCommand, appAuthoritySchema, grantCommandSchema, applyInstallationCommand, approvedGrantSchema, declaredOperationsSchema, installationCommandSchema, installationIdSchema, installationRefusalSchema, installationSchema, grantChangeSchema, } from "./installation.js";
3
+ export { permissionPinsSchema, permissionSaveSchema, appPermissionsWireSchema, appPermissionPageSchema, permissionScreen, draftOf, editPermissions, planGrantChange, rebaseDraft, grantRequestFor, pendingCapabilities, } from "./permissions.js";
3
4
  export { admits, admitMethodMetadata, appInvocationCeiling, approvedBindingGrants, scopedBindings, grantsFor, gateRefusalSchema, gateRequestSchema, invocationGrantsSchema, } from "./gate.js";
4
5
  export { deriveDeclaredOperations, appCallOperation } from "./operations.js";
5
6
  export { appToolPolicySchema, } from "./tools.js";
7
+ export { permissionCatalog } from "./catalog.js";
@@ -2,11 +2,18 @@ import * as z from "zod";
2
2
  import * as Schema from "effect/Schema";
3
3
  import * as Result from "effect/Result";
4
4
  import { type AppDeclaration, type HostActor } from "@fungi.computer/puffball/app";
5
+ import type { OwnerState } from "../index.js";
5
6
  import type { CapabilityDescriptor } from "../capability-descriptor.js";
7
+ import type { HostPrincipal } from "./gate.js";
6
8
  /** Reuse the owning Effect codec at a JSON/storage boundary. */
7
9
  export declare function ownerCodec<A, I>(schema: Schema.Codec<A, I>): z.ZodPipe<z.ZodUnknown, z.ZodTransform<Awaited<A>, unknown>>;
8
10
  /** Installation names cannot contain the tenant separator. */
9
11
  export declare const installationIdSchema: z.ZodLazy<z.ZodString>;
12
+ /** A resource identity minted and resolved by the host, never by this module. */
13
+ export declare const resourceRefSchema: z.ZodLazy<z.ZodReadonly<z.ZodObject<{
14
+ kind: z.ZodString;
15
+ id: z.ZodString;
16
+ }, z.core.$strict>>>;
10
17
  export type ResourceRef = Exclude<ApprovedGrant["resources"], "tenant-scope">[number];
11
18
  /**
12
19
  * Consent approves capabilities, with explicit operation and resource ceilings.
@@ -14,14 +21,14 @@ export type ResourceRef = Exclude<ApprovedGrant["resources"], "tenant-scope">[nu
14
21
  * no new consent; a new capability does. Release selection intersects stored
15
22
  * operations instead of adding approvals. Each Worker call is still restricted
16
23
  * to that method's declared requires, never the App's complete capability set.
17
- * Only an approved install or set-grants command mints capabilityApproved.
24
+ * Only an approved install or change-grants command mints capabilityApproved.
18
25
  * Empty operation rows retain that consent; removing the capability revokes it.
19
26
  * route:app.methods rows record approval detail, not a method allowlist: narrowing
20
- * them in set-grants does not restrict methods using an approved capability.
27
+ * them in change-grants does not restrict methods using an approved capability.
21
28
  * Exact operation rows are enforced for capability routes and backend bindings.
22
29
  */
23
30
  export declare const approvedGrantSchema: z.ZodReadonly<z.ZodObject<{
24
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
31
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
25
32
  capabilityApproved: z.ZodLiteral<true>;
26
33
  operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
27
34
  resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
@@ -30,10 +37,86 @@ export declare const approvedGrantSchema: z.ZodReadonly<z.ZodObject<{
30
37
  }, z.core.$strict>>>>>]>;
31
38
  }, z.core.$strict>>;
32
39
  export type ApprovedGrant = Readonly<z.output<typeof approvedGrantSchema>>;
33
- export type GrantRequest = Extract<InstallationCommand, {
34
- kind: "install";
35
- }>["grants"];
36
- export type Approval = NonNullable<Installation["approval"]>;
40
+ /** A bounded owner edit. Unnamed approvals are not part of the command. */
41
+ export declare const grantChangeSchema: z.ZodReadonly<z.ZodObject<{
42
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
43
+ grant: z.ZodNullable<z.ZodReadonly<z.ZodObject<{
44
+ operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
45
+ resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
46
+ kind: z.ZodString;
47
+ id: z.ZodString;
48
+ }, z.core.$strict>>>>>]>;
49
+ }, z.core.$strict>>>;
50
+ }, z.core.$strict>>;
51
+ export type GrantChange = z.output<typeof grantChangeSchema>;
52
+ /** The owner and version that approved a fixed operation snapshot. */
53
+ export type Approval = Readonly<{
54
+ by: HostActor;
55
+ at: number;
56
+ authorityVersion: number;
57
+ }>;
58
+ /** The complete grant state. Hosts own storage and compare-and-set commits. */
59
+ export declare const appAuthoritySchema: z.ZodObject<{
60
+ authorityVersion: z.ZodLazy<z.ZodNumber>;
61
+ declaredOperationsDigest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
62
+ approvedGrants: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
63
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
64
+ capabilityApproved: z.ZodLiteral<true>;
65
+ operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
66
+ resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
67
+ kind: z.ZodString;
68
+ id: z.ZodString;
69
+ }, z.core.$strict>>>>>]>;
70
+ }, z.core.$strict>>>>>;
71
+ approval: z.ZodNullable<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
72
+ by: import("zod/mini").ZodMiniDiscriminatedUnion<[import("zod/mini").ZodMiniObject<{
73
+ kind: import("zod/mini").ZodMiniLiteral<"member">;
74
+ memberId: import("zod/mini").ZodMiniString<string>;
75
+ }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
76
+ kind: import("zod/mini").ZodMiniLiteral<"agent">;
77
+ agentId: import("zod/mini").ZodMiniString<string>;
78
+ }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
79
+ kind: import("zod/mini").ZodMiniLiteral<"team-key">;
80
+ keyId: import("zod/mini").ZodMiniString<string>;
81
+ }, z.core.$strip>], "kind">;
82
+ at: z.ZodNumber;
83
+ authorityVersion: z.ZodLazy<z.ZodNumber>;
84
+ }, z.core.$strict>>>>;
85
+ }, z.core.$strict>;
86
+ export type AppAuthority = z.output<typeof appAuthoritySchema>;
87
+ export declare const grantCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
88
+ kind: z.ZodLiteral<"install">;
89
+ }, z.core.$strict>, z.ZodObject<{
90
+ kind: z.ZodLiteral<"change-grants">;
91
+ changes: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
92
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
93
+ grant: z.ZodNullable<z.ZodReadonly<z.ZodObject<{
94
+ operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
95
+ resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
96
+ kind: z.ZodString;
97
+ id: z.ZodString;
98
+ }, z.core.$strict>>>>>]>;
99
+ }, z.core.$strict>>>;
100
+ }, z.core.$strict>>>>;
101
+ }, z.core.$strict>, z.ZodObject<{
102
+ kind: z.ZodLiteral<"select-release">;
103
+ }, z.core.$strict>, z.ZodObject<{
104
+ kind: z.ZodLiteral<"delete">;
105
+ }, z.core.$strict>], "kind">;
106
+ export type GrantCommand = z.output<typeof grantCommandSchema>;
107
+ export type GrantContext = Readonly<{
108
+ principal: HostPrincipal;
109
+ expectedVersion: number | null;
110
+ declaration: AppDeclaration;
111
+ declaredOperations: DeclaredOperations;
112
+ now: number;
113
+ }>;
114
+ export type GrantRefusal = Readonly<{
115
+ kind: "refused";
116
+ code: "stale_authority" | "not_owner" | "not_declared" | "invalid_command";
117
+ }>;
118
+ /** One host-independent approval policy; selection only intersects existing grants. */
119
+ export declare function applyGrantCommand(current: AppAuthority | null, rawCommand: GrantCommand, context: GrantContext): Result.Result<AppAuthority, GrantRefusal>;
37
120
  /** Immutable operation facts derived from descriptor methods and the binding registry. */
38
121
  export declare const declaredOperationsSchema: z.ZodLazy<z.ZodObject<{
39
122
  artifactDigest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
@@ -43,7 +126,7 @@ export declare const declaredOperationsSchema: z.ZodLazy<z.ZodObject<{
43
126
  digest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
44
127
  }, z.core.$strict>>>>;
45
128
  capabilities: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
46
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
129
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
47
130
  operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
48
131
  }, z.core.$strict>>>>;
49
132
  }, z.core.$strict>>;
@@ -55,7 +138,7 @@ export type CapabilityOperationDescriptor = Pick<CapabilityDescriptor, "id" | "m
55
138
  /** Resolved immutable Release plus host-owned installation and approval state. */
56
139
  export declare const installationSchema: z.ZodObject<{
57
140
  installationId: z.ZodLazy<z.ZodString>;
58
- instanceId: z.ZodNullable<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("../index.js").InstanceId, unknown>>>;
141
+ instanceId: z.ZodNullable<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("../instance-id.js").InstanceId, unknown>>>;
59
142
  appId: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").AppId, unknown>>;
60
143
  release: z.ZodPipe<z.ZodUnknown, z.ZodTransform<{
61
144
  readonly releaseId: import("@fungi.computer/puffball").ReleaseId;
@@ -74,7 +157,33 @@ export declare const installationSchema: z.ZodObject<{
74
157
  pinned: "pinned";
75
158
  floating: "floating";
76
159
  }>;
77
- authorityVersion: z.ZodLazy<z.ZodNumber>;
160
+ authority: z.ZodObject<{
161
+ authorityVersion: z.ZodLazy<z.ZodNumber>;
162
+ declaredOperationsDigest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
163
+ approvedGrants: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
164
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
165
+ capabilityApproved: z.ZodLiteral<true>;
166
+ operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
167
+ resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
168
+ kind: z.ZodString;
169
+ id: z.ZodString;
170
+ }, z.core.$strict>>>>>]>;
171
+ }, z.core.$strict>>>>>;
172
+ approval: z.ZodNullable<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
173
+ by: import("zod/mini").ZodMiniDiscriminatedUnion<[import("zod/mini").ZodMiniObject<{
174
+ kind: import("zod/mini").ZodMiniLiteral<"member">;
175
+ memberId: import("zod/mini").ZodMiniString<string>;
176
+ }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
177
+ kind: import("zod/mini").ZodMiniLiteral<"agent">;
178
+ agentId: import("zod/mini").ZodMiniString<string>;
179
+ }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
180
+ kind: import("zod/mini").ZodMiniLiteral<"team-key">;
181
+ keyId: import("zod/mini").ZodMiniString<string>;
182
+ }, z.core.$strip>], "kind">;
183
+ at: z.ZodNumber;
184
+ authorityVersion: z.ZodLazy<z.ZodNumber>;
185
+ }, z.core.$strict>>>>;
186
+ }, z.core.$strict>;
78
187
  status: z.ZodEnum<{
79
188
  enabled: "enabled";
80
189
  disabled: "disabled";
@@ -84,30 +193,6 @@ export declare const installationSchema: z.ZodObject<{
84
193
  private: "private";
85
194
  public: "public";
86
195
  }>;
87
- declaredOperationsDigest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
88
- approvedGrants: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
89
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
90
- capabilityApproved: z.ZodLiteral<true>;
91
- operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
92
- resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
93
- kind: z.ZodString;
94
- id: z.ZodString;
95
- }, z.core.$strict>>>>>]>;
96
- }, z.core.$strict>>>>>;
97
- approval: z.ZodNullable<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
98
- by: import("zod/mini").ZodMiniDiscriminatedUnion<[import("zod/mini").ZodMiniObject<{
99
- kind: import("zod/mini").ZodMiniLiteral<"member">;
100
- memberId: import("zod/mini").ZodMiniString<string>;
101
- }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
102
- kind: import("zod/mini").ZodMiniLiteral<"agent">;
103
- agentId: import("zod/mini").ZodMiniString<string>;
104
- }, z.core.$strip>, import("zod/mini").ZodMiniObject<{
105
- kind: import("zod/mini").ZodMiniLiteral<"team-key">;
106
- keyId: import("zod/mini").ZodMiniString<string>;
107
- }, z.core.$strip>], "kind">;
108
- at: z.ZodNumber;
109
- authorityVersion: z.ZodLazy<z.ZodNumber>;
110
- }, z.core.$strict>>>>;
111
196
  approvedAnonymousMethods: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
112
197
  name: z.ZodPipe<z.ZodUnknown, z.ZodTransform<string, unknown>>;
113
198
  digest: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("@fungi.computer/puffball").Sha256Digest, unknown>>;
@@ -130,14 +215,6 @@ export declare const installationSchema: z.ZodObject<{
130
215
  export type Installation = Readonly<z.output<typeof installationSchema>>;
131
216
  /** Host commands; floating targets have already been resolved to immutable Releases. */
132
217
  export declare const installationCommandSchema: z.ZodLazy<z.ZodDiscriminatedUnion<[z.ZodObject<{
133
- grants: z.ZodUnion<readonly [z.ZodLiteral<"none">, z.ZodLiteral<"declared">, z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
134
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
135
- operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
136
- resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
137
- kind: z.ZodString;
138
- id: z.ZodString;
139
- }, z.core.$strict>>>>>]>;
140
- }, z.core.$strict>>>>]>;
141
218
  release: z.ZodPipe<z.ZodUnknown, z.ZodTransform<{
142
219
  readonly releaseId: import("@fungi.computer/puffball").ReleaseId;
143
220
  readonly appId: import("@fungi.computer/puffball").AppId;
@@ -189,15 +266,17 @@ export declare const installationCommandSchema: z.ZodLazy<z.ZodDiscriminatedUnio
189
266
  public: "public";
190
267
  }>;
191
268
  }, z.core.$strict>, z.ZodObject<{
192
- kind: z.ZodLiteral<"set-grants">;
193
- grants: z.ZodUnion<readonly [z.ZodLiteral<"none">, z.ZodLiteral<"declared">, z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
194
- capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
195
- operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
196
- resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
197
- kind: z.ZodString;
198
- id: z.ZodString;
199
- }, z.core.$strict>>>>>]>;
200
- }, z.core.$strict>>>>]>;
269
+ kind: z.ZodLiteral<"change-grants">;
270
+ changes: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
271
+ capability: z.ZodPipe<z.ZodUnknown, z.ZodTransform<"approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "llm.generation" | "media.generation" | "games:servers" | "git.repository" | "apps.open" | "apps.call" | "app.storage" | "app.events.emit" | "team.workbenchHost" | "marketplace.browse" | "marketplace.purchase" | "workflow.run" | "workflow.publish" | "workflow.arm" | "world" | "channels.read" | "channels.personal.manage", unknown>>;
272
+ grant: z.ZodNullable<z.ZodReadonly<z.ZodObject<{
273
+ operations: z.ZodLazy<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
274
+ resources: z.ZodUnion<readonly [z.ZodLiteral<"tenant-scope">, z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
275
+ kind: z.ZodString;
276
+ id: z.ZodString;
277
+ }, z.core.$strict>>>>>]>;
278
+ }, z.core.$strict>>>;
279
+ }, z.core.$strict>>>>;
201
280
  }, z.core.$strict>, z.ZodObject<{
202
281
  kind: z.ZodLiteral<"approve-anonymous">;
203
282
  methods: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
@@ -246,3 +325,5 @@ export type InstallationReader = Readonly<{
246
325
  }>;
247
326
  /** Pure transition; hosts retain transactions, receipts, epochs and delivery. */
248
327
  export declare function applyInstallationCommand(current: Installation | null, rawCommand: InstallationCommand, context: InstallationContext): Result.Result<InstallationUpdate, InstallationRefusal>;
328
+ /** Only the committed installation may activate this exact owner selection. */
329
+ export declare function isCommittedInstallation(current: Installation | null, state: OwnerState, release: Installation["release"]): boolean;