Skip to content
API reference

apps

Kind Export Description
type alias PermissionCatalogEntry Consent and resource semantics belong to the grant owner, not its UI.
type alias HostPrincipal Attested by the host, never authenticated by decoding request JSON.
type alias GateRequest One decoded method, route, binding or catalog admission request.
type alias GateFacts Immutable values the host already read; resource/grantor freshness remains host-owned.
type alias InvocationGrants The explicit binding ceiling passed to an invocation frame.
type alias AppMethodDeclaration A declared method from the canonical Puffball API grammar.
type alias GateDecision Either an admitted scoped ceiling or one closed refusal code.
type alias AppMethodMetadataDecision Permission metadata only: this is neither an invocation grant nor input admission.
type alias ResourceRef Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias ApprovedGrant Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias GrantChange Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias Approval The owner and version that approved a fixed operation snapshot.
type alias AppAuthority Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias GrantCommand Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias GrantContext Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias GrantRefusal Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias DeclaredOperations Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias CapabilityOperationDescriptor Use the existing adapter’s permission and methods; hosts author no operation lists.
type alias Installation Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias InstallationCommand Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias InstallationContext Values captured by the host; identities and time are never generated by the reducer.
type alias InstallationRefusal Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias InstallationUpdate Installation records and pure admission rules; tenant state and commits stay host-owned.
type alias InstallationReader Read port for one host tenant; commits, receipts and revocation stay with that host.
type alias ResourceOption A host-provided resource identity and its display label.
type alias GrantRequestDecision How an App’s runtime permission request relates to the owner’s stored grants.
type alias PermissionDraft Capability approvals being edited; null removes the capability’s grant.
type alias PermissionEdit One switch, scope, resource or operation change applied to a draft.
type alias AppPermissionsWire Host-supplied authority and declared operations used to derive permission UI.
type alias PermissionScreen Catalog-derived permission groups, resource cells and operation switches.
type alias PermissionPins Generation, authority version and artifact digest fencing a permission edit.
type alias AppToolPolicy The authenticated attaching member is recorded when this policy is approved.
type alias AppToolAccess One installation binding constrained by an authenticated tool-policy approval.
type alias AppToolEntry Pre-read entries: the catalog never resolves installations or calls back into a host.
constant permissionCatalog Every capability selects one consent class and one resource grammar.
constant gateRequestSchema Requests select existing SDK methods, opaque backend calls and derived operation identities.
constant invocationGrantsSchema Binding grants have the exact S2 InvocationFacts shape and its maintained registry grammar.
constant gateRefusalSchema Ordered, closed refusal vocabulary; external methods always require approval.
constant installationIdSchema Installation names cannot contain the tenant separator.
constant approvedGrantSchema Consent approves capabilities, with explicit operation and resource ceilings. A Release adding a method that requires an already-approved capability needs no new consent; a new capability does. Release selection intersects stored operations instead of adding approvals. Each Worker call is still restricted to that method’s declared requires, never the App’s complete capability set. Only an approved install or change-grants command mints capabilityApproved. Empty operation rows retain that consent; removing the capability revokes it. route:app.methods rows record approval detail, not a method allowlist: narrowing them in change-grants does not restrict methods using an approved capability. Exact operation rows are enforced for capability routes and backend bindings.
constant grantChangeSchema A bounded owner edit. Unnamed approvals are not part of the command.
constant appAuthoritySchema The complete grant state. Hosts own storage and compare-and-set commits.
constant grantCommandSchema Installation records and pure admission rules; tenant state and commits stay host-owned.
constant declaredOperationsSchema Immutable operation facts derived from descriptor methods and the binding registry.
constant installationSchema Resolved immutable Release plus host-owned installation and approval state.
constant installationCommandSchema Host commands; floating targets have already been resolved to immutable Releases.
constant installationRefusalSchema Closed refusals: failed commands produce no installation update.
constant appPermissionsWireSchema Serializable host facts; the browser derives presentation, never authority.
constant permissionPinsSchema Owner-direct permission page and JSON projection. Copy stays in the catalog.
constant permissionSaveSchema Permission edit command coupled to the version pins read by the owner.
constant appPermissionPageSchema Owner permission-page identity, artifact and current permission facts.
constant appToolPolicySchema One App-tool access level, with its own freshness pin. An Agent’s comes from the owner’s stored direct approval; a key’s is computed fresh from its own Ear Tag grants (keyAppAccess), never stored as this shape – only read through it, for one call or one installation at a time.
function grantsFor() Intersect stored approvals with the current verified Release without widening resource selectors.
function approvedBindingGrants() Approved binding operations from an already verified declaration. Hosts still pin the selection/version/artifact and compare running frame grants as a subset.
function scopedBindings() Narrow captured binding operations to the method’s verified requirements and effect. The captured set is the ceiling; this never adds an operation or resource authority.
function appInvocationCeiling() Principal ceiling for invocation and metadata capture. Captures must pass this to scopedBindings; its default write ceiling does not encode caller access.
function admitMethodMetadata() Check a verified method’s Release, principal, effect and real capability consent. Captures have no mapped runtime input yet. This result cannot authorize execution: dispatch must still use admits, including its ordinary input validation. Input schemas are not compiled here; execution may still refuse invalid_input. Project captured bindings with appInvocationCeiling(facts).
function admits() Ordered admission only. Host freshness/resource admission and effect execution stay outside this pure gate.
function applyGrantCommand() One host-independent approval policy; selection only intersects existing grants.
function applyInstallationCommand() Pure transition; hosts retain transactions, receipts, epochs and delivery.
function appCallOperation() Approval identity for one UI-side target method; upgrades intersect these exact pairs.
function deriveDeclaredOperations() Sole derivation owner. Inputs are the verified Release declaration and existing host adapters.
function pendingCapabilities() Includes newly declared operations and capabilities the owner has narrowed.
function grantRequestFor() Bound the real SDK request; an Allow never silently widens selected resources.
function draftOf() The saved operation ceiling is the starting point, including empty operation rows.
function editPermissions() An edit changes one capability; unrelated saved operations and scopes are retained.
function planGrantChange() Only touched capability rows cross the save boundary.
function rebaseDraft() A conflict preserves the person’s edits while taking fresh untouched capabilities.
function permissionScreen() Every declared permission is visible, including removable saved resources no longer listed by the host.

PermissionCatalogEntrytype alias

Section titled “PermissionCatalogEntry”
Signature
type PermissionCatalogEntry = Readonly<{
group:
| "computers"
| "agents"
| "generation"
| "bazaar"
| "data"
| "workflows"
| "git"
| "channels"
| "apps"
| "shell"
| "other";
label: string;
caption: string;
description: string;
sigil: SigilName;
consent: "affordance" | "install" | "ask";
scope: "computer" | "agent" | null;
warning: string | null;
}>;

Consent and resource semantics belong to the grant owner, not its UI.


HostPrincipaltype alias

Section titled “HostPrincipal”
Signature
type HostPrincipal = Readonly<{
actor:
| HostActor
| Readonly<{
kind: "visitor";
}>;
role: "owner" | "member" | null;
}>;

Attested by the host, never authenticated by decoding request JSON.


GateRequesttype alias

Section titled “GateRequest”
Signature
type GateRequest = z.output<typeof gateRequestSchema>;

One decoded method, route, binding or catalog admission request.


GateFactstype alias

Section titled “GateFacts”
Signature
type GateFacts = Readonly<{
principal: HostPrincipal;
installation: Readonly<
Pick<Installation, "status" | "visibility" | "instanceId" | "authority"> &
object
>;
declaration: AppDeclaration;
declaredOperations: DeclaredOperations;
api: AppApi | null;
access: AppToolAccess | null;
pins?: Readonly<{
authorityVersion: number;
artifactDigest: string;
}>;
}>;

Immutable values the host already read; resource/grantor freshness remains host-owned.


InvocationGrantstype alias

Section titled “InvocationGrants”
Signature
type InvocationGrants = z.output<typeof invocationGrantsSchema>;

The explicit binding ceiling passed to an invocation frame.


AppMethodDeclarationtype alias

Section titled “AppMethodDeclaration”
Signature
type AppMethodDeclaration = AppApi["methods"][string];

A declared method from the canonical Puffball API grammar.


GateDecisiontype alias

Section titled “GateDecision”
Signature
type GateDecision =
| Readonly<{
kind: "admitted";
grants: InvocationGrants;
method?: AppMethodDeclaration;
}>
| z.output<typeof gateRefusalSchema>;

Either an admitted scoped ceiling or one closed refusal code.


AppMethodMetadataDecisiontype alias

Section titled “AppMethodMetadataDecision”
Signature
type AppMethodMetadataDecision =
| Readonly<{
kind: "admitted";
method: AppMethodDeclaration;
}>
| z.output<typeof gateRefusalSchema>;

Permission metadata only: this is neither an invocation grant nor input admission.


ResourceReftype alias

Section titled “ResourceRef”
Signature
type ResourceRef = Exclude<ApprovedGrant["resources"], "tenant-scope">[number];

Installation records and pure admission rules; tenant state and commits stay host-owned.


ApprovedGranttype alias

Section titled “ApprovedGrant”
Signature
type ApprovedGrant = Readonly<z.output<typeof approvedGrantSchema>>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


GrantChangetype alias

Section titled “GrantChange”
Signature
type GrantChange = z.output<typeof grantChangeSchema>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


Signature
type Approval = Readonly<{
by: HostActor;
at: number;
authorityVersion: number;
}>;

The owner and version that approved a fixed operation snapshot.


AppAuthoritytype alias

Section titled “AppAuthority”
Signature
type AppAuthority = z.output<typeof appAuthoritySchema>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


GrantCommandtype alias

Section titled “GrantCommand”
Signature
type GrantCommand = z.output<typeof grantCommandSchema>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


GrantContexttype alias

Section titled “GrantContext”
Signature
type GrantContext = Readonly<{
principal: HostPrincipal;
expectedVersion: number | null;
declaration: AppDeclaration;
declaredOperations: DeclaredOperations;
now: number;
}>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


GrantRefusaltype alias

Section titled “GrantRefusal”
Signature
type GrantRefusal = Readonly<{
kind: "refused";
code: "stale_authority" | "not_owner" | "not_declared" | "invalid_command";
}>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


DeclaredOperationstype alias

Section titled “DeclaredOperations”
Signature
type DeclaredOperations = Readonly<z.output<typeof declaredOperationsSchema>>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


CapabilityOperationDescriptortype alias

Section titled “CapabilityOperationDescriptor”
Signature
type CapabilityOperationDescriptor = Pick<
CapabilityDescriptor,
"id" | "methods"
> &
Readonly<{
permission: ApprovedGrant["capability"];
}>;

Use the existing adapter’s permission and methods; hosts author no operation lists.


Installationtype alias

Section titled “Installation”
Signature
type Installation = Readonly<z.output<typeof installationSchema>>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


InstallationCommandtype alias

Section titled “InstallationCommand”
Signature
type InstallationCommand = z.output<typeof installationCommandSchema>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


InstallationContexttype alias

Section titled “InstallationContext”
Signature
type InstallationContext = Readonly<{
by: HostActor;
role: "owner" | "member" | null;
expectedVersion: number | null;
declaration: AppDeclaration;
declaredOperations: DeclaredOperations;
now: number;
identity: Pick<Installation, "installationId" | "instanceId">;
anonymousConsent?: Readonly<{
memberId: string;
}>;
}>;

Values captured by the host; identities and time are never generated by the reducer.


InstallationRefusaltype alias

Section titled “InstallationRefusal”
Signature
type InstallationRefusal = z.output<typeof installationRefusalSchema>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


InstallationUpdatetype alias

Section titled “InstallationUpdate”
Signature
type InstallationUpdate = Readonly<{
next: Installation;
authorityChanged: boolean;
}>;

Installation records and pure admission rules; tenant state and commits stay host-owned.


InstallationReadertype alias

Section titled “InstallationReader”
Signature
type InstallationReader = Readonly<{
list: Promise<readonly Readonly<{
installationId: string;
instanceId: 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;
}>[]>;
get: Promise<
| Readonly<{
installationId: string;
instanceId: 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>;
}>;

Read port for one host tenant; commits, receipts and revocation stay with that host.


ResourceOptiontype alias

Section titled “ResourceOption”
Signature
type ResourceOption = object;

A host-provided resource identity and its display label.

Signature
kind: string;
Signature
id: string;
Signature
label: string;

GrantRequestDecisiontype alias

Section titled “GrantRequestDecision”
Signature
type GrantRequestDecision =
| Readonly<{
kind: "covered";
}>
| Readonly<{
kind: "customize";
}>
| Readonly<{
kind: "refused";
code: "not_declared" | "stale_authority" | "window_scope_unavailable";
}>
| Readonly<{
kind: "ask";
adds: readonly GrantChange[];
command: Extract<
GrantCommand,
{
kind: "change-grants";
}
>;
}>;

How an App’s runtime permission request relates to the owner’s stored grants.


PermissionDrafttype alias

Section titled “PermissionDraft”
Signature
type PermissionDraft = ReadonlyMap<
AppCapabilityId,
{
operations: readonly string[];
resources:
| "tenant-scope"
| readonly Readonly<{
kind: string;
id: string;
}>[];
} | null
>;

Capability approvals being edited; null removes the capability’s grant.


PermissionEdittype alias

Section titled “PermissionEdit”
Signature
type PermissionEdit =
| Readonly<{
kind: "switch" | "all";
capability: AppCapabilityId;
on: boolean;
}>
| Readonly<{
kind: "resource";
capability: AppCapabilityId;
resource: ResourceRef;
on: boolean;
}>
| Readonly<{
kind: "operation";
capability: AppCapabilityId;
operation: string;
on: boolean;
}>;

One switch, scope, resource or operation change applied to a draft.


AppPermissionsWiretype alias

Section titled “AppPermissionsWire”
Signature
type AppPermissionsWire = z.output<typeof appPermissionsWireSchema>;

Host-supplied authority and declared operations used to derive permission UI.


PermissionScreentype alias

Section titled “PermissionScreen”
Signature
type PermissionScreen = Readonly<{
canEdit: boolean;
pending: readonly AppCapabilityId[];
groups: readonly Readonly<{
id: PermissionCatalogEntry["group"];
scope: "computer" | "agent" | null;
columns: readonly object[];
rows: readonly Readonly<{
resource: ... | ...;
label: string;
cells: readonly ...;
}>[];
switches: readonly object & Readonly<...>[];
operations: readonly Readonly<{
capability: "apps.call";
operation: string;
on: boolean;
}>[];
}>[];
}>;

Catalog-derived permission groups, resource cells and operation switches.


PermissionPinstype alias

Section titled “PermissionPins”
Signature
type PermissionPins = z.output<typeof permissionPinsSchema>;

Generation, authority version and artifact digest fencing a permission edit.


AppToolPolicytype alias

Section titled “AppToolPolicy”
Signature
type AppToolPolicy = typeof appToolPolicySchema.Type;

The authenticated attaching member is recorded when this policy is approved.


AppToolAccesstype alias

Section titled “AppToolAccess”
Signature
type AppToolAccess = typeof appToolAccessSchema.Type;

One installation binding constrained by an authenticated tool-policy approval.


AppToolEntrytype alias

Section titled “AppToolEntry”
Signature
type AppToolEntry = Readonly<{
installation: Installation;
declaration: AppDeclaration;
declaredOperations: DeclaredOperations;
api: AppApi | null;
access: AppToolAccess | null;
}>;

Pre-read entries: the catalog never resolves installations or calls back into a host.

permissionCatalogconstant

Section titled “permissionCatalog”
Signature
const permissionCatalog: object;

Every capability selects one consent class and one resource grammar.

Name Type
approvals Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.list Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.manage Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.rename Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.avatar Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.toolPolicy Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.read Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
agent.send Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
computer.list Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
computer.readFile Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
computer.writeFile Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
computer.execute Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
llm.generation Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
media.generation Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
games:servers Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
git.repository Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
apps.open Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
apps.call Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
app.storage Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
app.events.emit Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
team.workbenchHost Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
marketplace.browse Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
marketplace.purchase Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
workflow.run Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
workflow.publish Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
workflow.arm Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
world Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
channels.read Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>
channels.personal.manage Readonly<{ group: | "computers" | "agents" | "generation" | "other" | "apps" | "workflows" | "git" | "bazaar" | "data" | "channels" | "shell"; label: string; caption: string; description: string; sigil: | "error" | "read" | "write" | "computer" | "list" | "run" | "agent" | "schedule" | "search" | "complete" | "oyster" | "bonsai" | "prints" | "inkcap" | "vishnu" | "generateText" | "generateMedia" | "buyApps" | "browseBazaar" | "chat" | "readConversations" | "listAgents" | "createAgents" | "sendPrompts" | "connected" | "working" | "installApps" | "restricted" | "trellis" | "games" | "tourtois" | "allApps" | "browser" | "internet" | "members" | "sell" | "fungi"; consent: "affordance" | "install" | "ask"; scope: "computer" | "agent" | null; warning: string | null; }>

gateRequestSchemaconstant

Section titled “gateRequestSchema”
Signature
const gateRequestSchema: ZodLazy<ZodDiscriminatedUnion<[ZodObject<{
kind: ZodLiteral<"method">;
name: ZodString;
input: ZodUnknown;
via: ZodEnum<{
ui: "ui";
agent: "agent";
mcp: "mcp";
workflow: "workflow";
}>;
resource: ZodOptional<ZodLazy<ZodReadonly<ZodObject<{
kind: ZodString;
id: ZodString;
}, $strict>>>>;
}, $strict>, ZodObject<{
kind: ZodLiteral<"capability">;
capability: ZodPipe<ZodUnknown, ZodTransform<
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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>>;
operation: ZodOptional<ZodString>;
resource: ZodUnion<readonly [ZodLazy<ZodReadonly<ZodObject<{
kind: ...;
id: ...;
}, $strict>>>, ZodLiteral<"any">]>;
}, $strict>, ZodObject<{
kind: ZodLiteral<"capability-route">;
capability: ZodPipe<ZodUnknown, ZodTransform<
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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>>;
operation: ZodString;
effect: ZodEnum<{
read: "read";
write: "write";
}>;
}, $strict>], "kind">>;

Requests select existing SDK methods, opaque backend calls and derived operation identities.


invocationGrantsSchemaconstant

Section titled “invocationGrantsSchema”
Signature
const invocationGrantsSchema: ZodLazy<
ZodReadonly<
ZodArray<
ZodObject<
{
binding: ZodPipe<
ZodUnknown,
ZodTransform<
| "BACKGROUND"
| "GIT"
| "EVENTS"
| "APPS"
| "WORKFLOWS"
| "APP_STORAGE"
| "MEDIA"
| "COMPUTER"
| "INBOX"
| "AGENTS",
unknown
>
>;
operations: ZodReadonly<ZodArray<ZodString>>;
},
$strict
>
>
>
>;

Binding grants have the exact S2 InvocationFacts shape and its maintained registry grammar.


gateRefusalSchemaconstant

Section titled “gateRefusalSchema”
Signature
const gateRefusalSchema: ZodLazy<
ZodObject<
{
kind: ZodLiteral<"refused">;
code: ZodEnum<{
unavailable: "unavailable";
stale_authority: "stale_authority";
not_declared: "not_declared";
not_approved: "not_approved";
level_too_low: "level_too_low";
approval_required: "approval_required";
requires_not_granted: "requires_not_granted";
invalid_input: "invalid_input";
visitor_read_only: "visitor_read_only";
}>;
},
$strict
>
>;

Ordered, closed refusal vocabulary; external methods always require approval.


installationIdSchemaconstant

Section titled “installationIdSchema”
Signature
const installationIdSchema: ZodLazy<ZodString>;

Installation names cannot contain the tenant separator.


approvedGrantSchemaconstant

Section titled “approvedGrantSchema”
Signature
const approvedGrantSchema: ZodReadonly<ZodObject<{
capability: ZodPipe<ZodUnknown, ZodTransform<
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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>>;
capabilityApproved: ZodLiteral<true>;
operations: ZodLazy<ZodReadonly<ZodArray<ZodString>>>;
resources: ZodUnion<readonly [ZodLiteral<"tenant-scope">, ZodReadonly<ZodArray<ZodLazy<ZodReadonly<ZodObject<{
kind: ...;
id: ...;
}, $strict>>>>>]>;
}, $strict>>;

Consent approves capabilities, with explicit operation and resource ceilings. A Release adding a method that requires an already-approved capability needs no new consent; a new capability does. Release selection intersects stored operations instead of adding approvals. Each Worker call is still restricted to that method’s declared requires, never the App’s complete capability set. Only an approved install or change-grants command mints capabilityApproved. Empty operation rows retain that consent; removing the capability revokes it. route:app.methods rows record approval detail, not a method allowlist: narrowing them in change-grants does not restrict methods using an approved capability. Exact operation rows are enforced for capability routes and backend bindings.


grantChangeSchemaconstant

Section titled “grantChangeSchema”
Signature
const grantChangeSchema: ZodReadonly<ZodObject<{
capability: ZodPipe<ZodUnknown, ZodTransform<
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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>>;
grant: ZodNullable<ZodReadonly<ZodObject<{
operations: ZodLazy<ZodReadonly<ZodArray<ZodString>>>;
resources: ZodUnion<readonly [ZodLiteral<"tenant-scope">, ZodReadonly<ZodArray<...>>]>;
}, $strict>>>;
}, $strict>>;

A bounded owner edit. Unnamed approvals are not part of the command.


appAuthoritySchemaconstant

Section titled “appAuthoritySchema”
Signature
const appAuthoritySchema: ZodObject<{
authorityVersion: ZodLazy<ZodNumber>;
declaredOperationsDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
approvedGrants: ZodLazy<ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<ZodUnknown, ZodTransform<
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ..., unknown>>;
capabilityApproved: ZodLiteral<true>;
operations: ZodLazy<ZodReadonly<ZodArray<...>>>;
resources: ZodUnion<readonly [ZodLiteral<...>, ZodReadonly<...>]>;
}, $strict>>>>>;
approval: ZodNullable<ZodLazy<ZodReadonly<ZodObject<{
by: ZodMiniDiscriminatedUnion<[ZodMiniObject<{
kind: ...;
memberId: ...;
}, $strip>, ZodMiniObject<{
kind: ...;
agentId: ...;
}, $strip>, ZodMiniObject<{
kind: ...;
keyId: ...;
}, $strip>], "kind">;
at: ZodNumber;
authorityVersion: ZodLazy<ZodNumber>;
}, $strict>>>>;
}, $strict>;

The complete grant state. Hosts own storage and compare-and-set commits.


grantCommandSchemaconstant

Section titled “grantCommandSchema”
Signature
const grantCommandSchema: ZodDiscriminatedUnion<[ZodObject<{
kind: ZodLiteral<"install">;
}, $strict>, ZodObject<{
kind: ZodLiteral<"change-grants">;
changes: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<ZodUnknown, ZodTransform<..., ...>>;
grant: ZodNullable<ZodReadonly<...>>;
}, $strict>>>>;
}, $strict>, ZodObject<{
kind: ZodLiteral<"select-release">;
}, $strict>, ZodObject<{
kind: ZodLiteral<"delete">;
}, $strict>], "kind">;

Installation records and pure admission rules; tenant state and commits stay host-owned.


declaredOperationsSchemaconstant

Section titled “declaredOperationsSchema”
Signature
const declaredOperationsSchema: ZodLazy<ZodObject<{
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
digest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
anonymousMethods: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
name: ZodPipe<ZodUnknown, ZodTransform<string, unknown>>;
digest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
}, $strict>>>>;
capabilities: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<ZodUnknown, ZodTransform<
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ...
| ..., unknown>>;
operations: ZodLazy<ZodReadonly<ZodArray<...>>>;
}, $strict>>>>;
}, $strict>>;

Immutable operation facts derived from descriptor methods and the binding registry.


installationSchemaconstant

Section titled “installationSchema”
Signature
const installationSchema: ZodObject<{
installationId: ZodLazy<ZodString>;
instanceId: ZodNullable<ZodPipe<ZodUnknown, ZodTransform<InstanceId, unknown>>>;
appId: ZodPipe<ZodUnknown, ZodTransform<AppId, unknown>>;
release: ZodPipe<ZodUnknown, ZodTransform<{
releaseId: ReleaseId;
appId: AppId;
artifact: {
artifactRef: ArtifactRef;
artifactDigest: Sha256Digest;
provenance: {
sourceRevision: SourceRevision;
sourceTreeDigest: Sha256Digest;
buildRecipeDigest: Sha256Digest;
};
};
}, unknown>>;
releasePin: ZodEnum<{
pinned: "pinned";
floating: "floating";
}>;
authority: ZodObject<{
authorityVersion: ZodLazy<ZodNumber>;
declaredOperationsDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
approvedGrants: ZodLazy<ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<..., ...>;
capabilityApproved: ZodLiteral<...>;
operations: ZodLazy<...>;
resources: ZodUnion<...>;
}, $strict>>>>>;
approval: ZodNullable<ZodLazy<ZodReadonly<ZodObject<{
by: ZodMiniDiscriminatedUnion<[..., ..., ...], "kind">;
at: ZodNumber;
authorityVersion: ZodLazy<ZodNumber>;
}, $strict>>>>;
}, $strict>;
status: ZodEnum<{
enabled: "enabled";
disabled: "disabled";
deleted: "deleted";
}>;
visibility: ZodEnum<{
private: "private";
public: "public";
}>;
approvedAnonymousMethods: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
name: ZodPipe<ZodUnknown, ZodTransform<string, unknown>>;
digest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
}, $strict>>>>;
anonymousApproval: ZodNullable<ZodLazy<ZodReadonly<ZodObject<{
by: ZodMiniDiscriminatedUnion<[ZodMiniObject<{
kind: ...;
memberId: ...;
}, $strip>, ZodMiniObject<{
kind: ...;
agentId: ...;
}, $strip>, ZodMiniObject<{
kind: ...;
keyId: ...;
}, $strip>], "kind">;
at: ZodNumber;
authorityVersion: ZodLazy<ZodNumber>;
}, $strict>>>>;
}, $strict>;

Resolved immutable Release plus host-owned installation and approval state.


installationCommandSchemaconstant

Section titled “installationCommandSchema”
Signature
const installationCommandSchema: ZodLazy<
ZodDiscriminatedUnion<
[
ZodObject<
{
release: ZodPipe<
ZodUnknown,
ZodTransform<
{
releaseId: ReleaseId;
appId: AppId;
artifact: {
artifactRef: ArtifactRef;
artifactDigest: Sha256Digest;
provenance: {
sourceRevision: SourceRevision;
sourceTreeDigest: Sha256Digest;
buildRecipeDigest: Sha256Digest;
};
};
},
unknown
>
>;
releasePin: ZodEnum<{
pinned: "pinned";
floating: "floating";
}>;
kind: ZodLiteral<"install">;
},
$strict
>,
ZodObject<
{
release: ZodPipe<
ZodUnknown,
ZodTransform<
{
releaseId: ReleaseId;
appId: AppId;
artifact: {
artifactRef: ArtifactRef;
artifactDigest: Sha256Digest;
provenance: {
sourceRevision: SourceRevision;
sourceTreeDigest: Sha256Digest;
buildRecipeDigest: Sha256Digest;
};
};
},
unknown
>
>;
releasePin: ZodEnum<{
pinned: "pinned";
floating: "floating";
}>;
kind: ZodLiteral<"select-release">;
},
$strict
>,
ZodObject<
{
kind: ZodLiteral<"set-status">;
status: ZodEnum<{
enabled: "enabled";
disabled: "disabled";
deleted: "deleted";
}>;
},
$strict
>,
],
"kind"
>
>;

Host commands; floating targets have already been resolved to immutable Releases.


installationRefusalSchemaconstant

Section titled “installationRefusalSchema”
Signature
const installationRefusalSchema: ZodLazy<
ZodObject<
{
kind: ZodLiteral<"refused">;
code: ZodEnum<{
unavailable: "unavailable";
stale_authority: "stale_authority";
not_declared: "not_declared";
release_app_mismatch: "release_app_mismatch";
not_owner: "not_owner";
invalid_command: "invalid_command";
}>;
},
$strict
>
>;

Closed refusals: failed commands produce no installation update.


appPermissionsWireSchemaconstant

Section titled “appPermissionsWireSchema”
Signature
const appPermissionsWireSchema: ZodObject<{
authority: ZodObject<{
authorityVersion: ZodLazy<ZodNumber>;
declaredOperationsDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
approvedGrants: ZodLazy<ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<..., ...>;
capabilityApproved: ZodLiteral<...>;
operations: ZodLazy<...>;
resources: ZodUnion<...>;
}, $strict>>>>>;
approval: ZodNullable<ZodLazy<ZodReadonly<ZodObject<{
by: ZodMiniDiscriminatedUnion<[..., ..., ...], "kind">;
at: ZodNumber;
authorityVersion: ZodLazy<ZodNumber>;
}, $strict>>>>;
}, $strict>;
declaredOperations: ZodLazy<ZodObject<{
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
digest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
anonymousMethods: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
name: ZodPipe<..., ...>;
digest: ZodPipe<..., ...>;
}, $strict>>>>;
capabilities: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ZodPipe<..., ...>;
operations: ZodLazy<...>;
}, $strict>>>>;
}, $strict>>;
}, $strict>;

Serializable host facts; the browser derives presentation, never authority.


permissionPinsSchemaconstant

Section titled “permissionPinsSchema”
Signature
const permissionPinsSchema: ZodObject<
{
storeGeneration: ZodString;
authorityVersion: ZodNumber;
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
},
$strict
>;

Owner-direct permission page and JSON projection. Copy stays in the catalog.


permissionSaveSchemaconstant

Section titled “permissionSaveSchema”
Signature
const permissionSaveSchema: ZodObject<{
storeGeneration: ZodString;
authorityVersion: ZodNumber;
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
command: ZodDiscriminatedUnion<[ZodObject<{
kind: ZodLiteral<"install">;
}, $strict>, ZodObject<{
kind: ZodLiteral<"change-grants">;
changes: ZodReadonly<ZodArray<ZodReadonly<ZodObject<{
capability: ...;
grant: ...;
}, $strict>>>>;
}, $strict>, ZodObject<{
kind: ZodLiteral<"select-release">;
}, $strict>, ZodObject<{
kind: ZodLiteral<"delete">;
}, $strict>], "kind">;
}, $strict>;

Permission edit command coupled to the version pins read by the owner.


appPermissionPageSchemaconstant

Section titled “appPermissionPageSchema”
Signature
const appPermissionPageSchema: ZodObject<{
storeGeneration: ZodString;
installationId: ZodString;
appId: ZodString;
appName: ZodString;
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
permissions: ZodObject<{
authority: ZodObject<{
authorityVersion: ZodLazy<ZodNumber>;
declaredOperationsDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
approvedGrants: ZodLazy<ZodReadonly<ZodArray<ZodReadonly<ZodObject<..., ...>>>>>;
approval: ZodNullable<ZodLazy<ZodReadonly<ZodObject<{
by: ...;
at: ...;
authorityVersion: ...;
}, $strict>>>>;
}, $strict>;
declaredOperations: ZodLazy<ZodObject<{
artifactDigest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
digest: ZodPipe<ZodUnknown, ZodTransform<Sha256Digest, unknown>>;
anonymousMethods: ZodReadonly<ZodArray<ZodReadonly<ZodObject<..., ...>>>>;
capabilities: ZodReadonly<ZodArray<ZodReadonly<ZodObject<..., ...>>>>;
}, $strict>>;
}, $strict>;
}, $strict>;

Owner permission-page identity, artifact and current permission facts.


appToolPolicySchemaconstant

Section titled “appToolPolicySchema”
Signature
const appToolPolicySchema: Struct<{
level: Literals<readonly ["read", "write"]>;
revision: NonEmptyString;
grantedBy: NonEmptyString;
}>;

One App-tool access level, with its own freshness pin. An Agent’s comes from the owner’s stored direct approval; a key’s is computed fresh from its own Ear Tag grants (keyAppAccess), never stored as this shape – only read through it, for one call or one installation at a time.

Signature
function grantsFor(
installation,
declaration,
snapshot,
capability,
resource?,
): Readonly<
Readonly<{
capability:
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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";
capabilityApproved: true;
operations: readonly string[];
resources:
| "tenant-scope"
| readonly Readonly<{
kind: string;
id: string;
}>[];
}>
> | null;

Intersect stored approvals with the current verified Release without widening resource selectors.

Parameter Type Default value
installation Pick<GateFacts["installation"], "status" | "authority" | "artifactDigest"> undefined
declaration AppDeclaration undefined
snapshot DeclaredOperations undefined
capability | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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" undefined
resource | "any" | Readonly<{ kind: string; id: string; }> "any"

| Readonly<Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>> | null


approvedBindingGrants()function

Section titled “approvedBindingGrants()”
Signature
function approvedBindingGrants(installation, declaration): readonly object[];

Approved binding operations from an already verified declaration. Hosts still pin the selection/version/artifact and compare running frame grants as a subset.

Parameter Type
installation Pick<GateFacts["installation"], "status" | "authority">
declaration AppDeclaration

readonly object[]


scopedBindings()function

Section titled “scopedBindings()”
Signature
function scopedBindings(captured, method?, ceiling?): readonly object[];

Narrow captured binding operations to the method’s verified requirements and effect. The captured set is the ceiling; this never adds an operation or resource authority.

Parameter Type Default value
captured readonly object[] undefined
method? Readonly<{ description: string; input: object; output: object; effect: "read" | "write" | "external"; requires: readonly ( | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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")[]; pending?: true; hidden?: true; anonymous?: true; present?: Readonly<{ verb: string; }>; }> undefined
ceiling? "read" | "write" "write"

readonly object[]


appInvocationCeiling()function

Section titled “appInvocationCeiling()”
Signature
function appInvocationCeiling(facts): "read" | "write";

Principal ceiling for invocation and metadata capture. Captures must pass this to scopedBindings; its default write ceiling does not encode caller access.

Parameter Type
facts Pick<GateFacts, "principal" | "access">

"read" | "write"


admitMethodMetadata()function

Section titled “admitMethodMetadata()”
Signature
function admitMethodMetadata(facts, name): AppMethodMetadataDecision;

Check a verified method’s Release, principal, effect and real capability consent. Captures have no mapped runtime input yet. This result cannot authorize execution: dispatch must still use admits, including its ordinary input validation. Input schemas are not compiled here; execution may still refuse invalid_input. Project captured bindings with appInvocationCeiling(facts).

Parameter Type
facts GateFacts
name string

AppMethodMetadataDecision


Signature
function admits(facts, rawRequest): GateDecision;

Ordered admission only. Host freshness/resource admission and effect execution stay outside this pure gate.

Parameter Type
facts GateFacts
rawRequest | { kind: "method"; name: string; input: unknown; via: "ui" | "agent" | "mcp" | "workflow"; resource?: Readonly<{ kind: string; id: string; }>; } | { kind: "capability"; capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; operation?: string; resource: | "any" | Readonly<{ kind: string; id: string; }>; } | { kind: "capability-route"; capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; operation: string; effect: "read" | "write"; } | { kind: "binding"; binding: | "BACKGROUND" | "GIT" | "EVENTS" | "APPS" | "WORKFLOWS" | "APP_STORAGE" | "MEDIA" | "COMPUTER" | "INBOX" | "AGENTS"; operation: string; } | { kind: "list-tools"; } | { kind: "backend"; }

GateDecision


applyGrantCommand()function

Section titled “applyGrantCommand()”
Signature
function applyGrantCommand(
current,
rawCommand,
context,
): Result<
{
authorityVersion: number;
declaredOperationsDigest: Sha256Digest;
approvedGrants: readonly Readonly<{
capability:
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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";
capabilityApproved: true;
operations: readonly string[];
resources:
| "tenant-scope"
| readonly Readonly<{
kind: string;
id: string;
}>[];
}>[];
approval: Readonly<{
by:
| {
kind: "member";
memberId: string;
}
| {
kind: "agent";
agentId: string;
}
| {
kind: "team-key";
keyId: string;
};
at: number;
authorityVersion: number;
}> | null;
},
Readonly<{
kind: "refused";
code: "stale_authority" | "not_declared" | "not_owner" | "invalid_command";
}>
>;

One host-independent approval policy; selection only intersects existing grants.

Parameter Type
current | { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; } | null
rawCommand | { kind: "install"; } | { kind: "change-grants"; changes: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; grant: | Readonly<{ operations: readonly string[]; resources: "tenant-scope" | readonly Readonly<…>[]; }> | null; }>[]; } | { kind: "select-release"; } | { kind: "delete"; }
context GrantContext

Result<{ authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }, Readonly<{ kind: "refused"; code: "stale_authority" | "not_declared" | "not_owner" | "invalid_command"; }>>


applyInstallationCommand()function

Section titled “applyInstallationCommand()”
Signature
function applyInstallationCommand(
current,
rawCommand,
context,
): Result<
Readonly<{
next: Installation;
authorityChanged: boolean;
}>,
{
kind: "refused";
code:
| "unavailable"
| "stale_authority"
| "not_declared"
| "release_app_mismatch"
| "not_owner"
| "invalid_command";
}
>;

Pure transition; hosts retain transactions, receipts, epochs and delivery.

Parameter Type
current | Readonly<{ installationId: string; instanceId: InstanceId | null; appId: AppId; release: { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }; releasePin: "pinned" | "floating"; authority: { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: …; id: …; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }; status: "enabled" | "disabled" | "deleted"; visibility: "private" | "public"; approvedAnonymousMethods: readonly Readonly<{ name: string; digest: Sha256Digest; }>[]; anonymousApproval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }> | null
rawCommand | { release: { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }; releasePin: "pinned" | "floating"; kind: "install"; } | { release: { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }; releasePin: "pinned" | "floating"; kind: "select-release"; } | { kind: "set-status"; status: "enabled" | "disabled" | "deleted"; } | { kind: "set-visibility"; visibility: "private" | "public"; } | { kind: "change-grants"; changes: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; grant: | Readonly<{ operations: readonly string[]; resources: "tenant-scope" | readonly Readonly<…>[]; }> | null; }>[]; } | { kind: "approve-anonymous"; methods: readonly Readonly<{ name: string; digest: Sha256Digest; }>[]; }
context InstallationContext

Result<Readonly<{ next: Installation; authorityChanged: boolean; }>, { kind: "refused"; code: | "unavailable" | "stale_authority" | "not_declared" | "release_app_mismatch" | "not_owner" | "invalid_command"; }>


appCallOperation()function

Section titled “appCallOperation()”
Signature
function appCallOperation(appId, method): string;

Approval identity for one UI-side target method; upgrades intersect these exact pairs.

Parameter Type
appId string
method string

string


deriveDeclaredOperations()function

Section titled “deriveDeclaredOperations()”
Signature
function deriveDeclaredOperations(
release,
declaration,
descriptors,
): Promise<
Readonly<{
artifactDigest: Sha256Digest;
digest: Sha256Digest;
anonymousMethods: readonly Readonly<{
name: string;
digest: Sha256Digest;
}>[];
capabilities: readonly Readonly<{
capability:
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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";
operations: readonly string[];
}>[];
}>
>;

Sole derivation owner. Inputs are the verified Release declaration and existing host adapters.

Parameter Type
release { releaseId: ReleaseId; appId: AppId; artifact: { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }; }
release.releaseId ReleaseId
release.appId AppId
release.artifact { artifactRef: ArtifactRef; artifactDigest: Sha256Digest; provenance: { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }; }
release.artifact.artifactRef ArtifactRef
release.artifact.artifactDigest Sha256Digest
release.artifact.provenance { sourceRevision: SourceRevision; sourceTreeDigest: Sha256Digest; buildRecipeDigest: Sha256Digest; }
release.artifact.provenance.sourceRevision SourceRevision
release.artifact.provenance.sourceTreeDigest Sha256Digest
release.artifact.provenance.buildRecipeDigest Sha256Digest
declaration AppDeclaration
descriptors readonly CapabilityOperationDescriptor[]

Promise<Readonly<{ artifactDigest: Sha256Digest; digest: Sha256Digest; anonymousMethods: readonly Readonly<{ name: string; digest: Sha256Digest; }>[]; capabilities: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; operations: readonly string[]; }>[]; }>>


pendingCapabilities()function

Section titled “pendingCapabilities()”
Signature
function pendingCapabilities(
authority,
declaration,
declaredOperations,
): readonly (
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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"
)[];

Includes newly declared operations and capabilities the owner has narrowed.

Parameter Type
authority Pick<AppAuthority, "approvedGrants">
declaration Pick<AppDeclaration, "capabilities">
declaredOperations DeclaredOperations

readonly ( | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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")[]


grantRequestFor()function

Section titled “grantRequestFor()”
Signature
function grantRequestFor(
authority,
facts,
request,
window,
): GrantRequestDecision;

Bound the real SDK request; an Allow never silently widens selected resources.

Parameter Type
authority { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }
authority.authorityVersion number
authority.declaredOperationsDigest Sha256Digest
authority.approvedGrants readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]
authority.approval | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null
facts Readonly<{ declaration: Pick<AppDeclaration, "capabilities">; declaredOperations: DeclaredOperations; }>
request AppPermissionRequest
window Readonly<{ computerId: string | null; }>

GrantRequestDecision


Signature
function draftOf(authority): PermissionDraft;

The saved operation ceiling is the starting point, including empty operation rows.

Parameter Type
authority { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }
authority.authorityVersion number
authority.declaredOperationsDigest Sha256Digest
authority.approvedGrants readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]
authority.approval | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null

PermissionDraft


editPermissions()function

Section titled “editPermissions()”
Signature
function editPermissions(draft, edit, declared): PermissionDraft;

An edit changes one capability; unrelated saved operations and scopes are retained.

Parameter Type
draft PermissionDraft
edit PermissionEdit
declared DeclaredOperations

PermissionDraft


planGrantChange()function

Section titled “planGrantChange()”
Signature
function planGrantChange(
baseline,
draft,
): readonly Readonly<{
capability:
| "computer.list"
| "computer.readFile"
| "computer.writeFile"
| "computer.execute"
| "approvals"
| "agent.list"
| "agent.manage"
| "agent.rename"
| "agent.avatar"
| "agent.toolPolicy"
| "agent.read"
| "agent.send"
| "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";
grant: Readonly<{
operations: readonly string[];
resources:
| "tenant-scope"
| readonly Readonly<{
kind: string;
id: string;
}>[];
}> | null;
}>[];

Only touched capability rows cross the save boundary.

Parameter Type
baseline { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }
baseline.authorityVersion number
baseline.declaredOperationsDigest Sha256Digest
baseline.approvedGrants readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]
baseline.approval | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null
draft PermissionDraft

readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; grant: | Readonly<{ operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }> | null; }>[]


rebaseDraft()function

Section titled “rebaseDraft()”
Signature
function rebaseDraft(draft, baseline, current): PermissionDraft;

A conflict preserves the person’s edits while taking fresh untouched capabilities.

Parameter Type
draft PermissionDraft
baseline { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }
baseline.authorityVersion number
baseline.declaredOperationsDigest Sha256Digest
baseline.approvedGrants readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]
baseline.approval | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null
current { authorityVersion: number; declaredOperationsDigest: Sha256Digest; approvedGrants: readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]; approval: | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null; }
current.authorityVersion number
current.declaredOperationsDigest Sha256Digest
current.approvedGrants readonly Readonly<{ capability: | "computer.list" | "computer.readFile" | "computer.writeFile" | "computer.execute" | "approvals" | "agent.list" | "agent.manage" | "agent.rename" | "agent.avatar" | "agent.toolPolicy" | "agent.read" | "agent.send" | "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"; capabilityApproved: true; operations: readonly string[]; resources: | "tenant-scope" | readonly Readonly<{ kind: string; id: string; }>[]; }>[]
current.approval | Readonly<{ by: | { kind: "member"; memberId: string; } | { kind: "agent"; agentId: string; } | { kind: "team-key"; keyId: string; }; at: number; authorityVersion: number; }> | null

PermissionDraft


permissionScreen()function

Section titled “permissionScreen()”
Signature
function permissionScreen(input): PermissionScreen;

Every declared permission is visible, including removable saved resources no longer listed by the host.

Parameter Type
input object & Readonly<{ resources: readonly ResourceOption[]; canEdit: boolean; }>

PermissionScreen