1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
{
"lexicon": 1,
"id": "com.fedfork.exec.wasm.module",
"defs": {
"main": {
"type": "record",
"key": "any",
"description": "A sandboxed WebAssembly module that turns user input into XRPC calls made with the session of an OAuth client metadata record. A module may run over several rounds: each output can name a next entry and state, and the host passes the call results back in.",
"record": {
"type": "object",
"required": [
"name",
"module",
"abi",
"actions",
"createdAt"
],
"properties": {
"name": {
"type": "string",
"maxLength": 2560,
"maxGraphemes": 256
},
"description": {
"type": "string",
"maxLength": 30000,
"maxGraphemes": 3000
},
"module": {
"type": "blob",
"accept": [
"application/wasm"
],
"maxSize": 4194304
},
"abi": {
"type": "string",
"maxLength": 256,
"knownValues": [
"emdash-wasm-json-v1"
]
},
"session": {
"type": "ref",
"ref": "com.atproto.repo.strongRef",
"description": "The com.fedfork.exec.oauth.clientMetadata record whose session the module's calls use. Absent for a module that makes no session calls of its own (a policy module in a composition)."
},
"source": {
"type": "ref",
"ref": "com.atproto.repo.strongRef",
"description": "The com.fedfork.exec.source.manifest record listing the source files and the build that produced the module blob."
},
"actions": {
"type": "array",
"maxLength": 256,
"items": {
"type": "ref",
"ref": "#action"
}
},
"calls": {
"type": "array",
"maxLength": 256,
"description": "NSIDs the module may ask the host to call. The host refuses any other call. When absent, the session's granted scopes are the only limit. Includes host pseudo-calls, handled by the host and never sent to a PDS: com.fedfork.exec.attest (sign a record), com.fedfork.exec.webrtc.connect (datachannel to a guest VM), com.fedfork.exec.iroh.connect (dial an iroh ticket).",
"items": {
"type": "string",
"format": "nsid"
}
},
"hooks": {
"type": "array",
"maxLength": 256,
"description": "NSIDs the module calls that another party must serve: a composition routes each to an instance's entry or a caller handler. Not sent to the session's PDS.",
"items": {
"type": "ref",
"ref": "#hook"
}
},
"implements": {
"type": "array",
"maxLength": 256,
"description": "Hook contracts an entry of this module serves; a hook default routes to the entry named here.",
"items": {
"type": "ref",
"ref": "#implementation"
}
},
"config": {
"type": "array",
"maxLength": 256,
"description": "The input a composition's instance of this module may give it: every key of an instance's input is one of these fields, of its type; a required one must be given. None: no input.",
"items": {
"type": "ref",
"ref": "#field"
}
},
"anyHooks": {
"type": "boolean",
"description": "A relay whose routed NSIDs its input names (ingress routes): a composition may route any NSID from it, not only its hooks and calls."
},
"anyRecords": {
"type": "array",
"maxLength": 256,
"description": "Collections where the module may update and delete records it did not create. In every other collection the host lets it update and delete only records it saw the module create.",
"items": {
"type": "string",
"format": "nsid"
}
},
"http": {
"type": "array",
"maxLength": 256,
"description": "Origins (scheme://host[:port]) the module's com.fedfork.exec.http.fetch calls may reach, or \"*\" for any the host allows; a request goes out only to an origin the host allows too, with the host's own headers (API keys) added.",
"items": {
"type": "string",
"maxLength": 2048
}
},
"didkey": {
"type": "ref",
"ref": "#didkey",
"description": "The host holds a P-256 did:key for the module (sealed per module record) and answers the com.fedfork.exec.didkey.* pseudo-calls."
},
"createdAt": {
"type": "string",
"format": "datetime"
}
}
}
},
"hook": {
"type": "object",
"required": [
"nsid",
"reason"
],
"properties": {
"nsid": {
"type": "string",
"format": "nsid",
"description": "The contract: a lexicon (procedure input and output)."
},
"entries": {
"type": "array",
"maxLength": 256,
"description": "The entries that call it (absent: every entry). A composition checks a required hook only for the entries its edges and policies reach, and the root run's entry.",
"items": {
"type": "string",
"maxLength": 256
}
},
"required": {
"type": "boolean",
"description": "With no route, no default and (for a transport: an NSID com.fedfork.exec.<name>.connect also in calls) not provided by the host, a composition is refused at load and a run fails at start. Default false: an unrouted hook without a default answers null (skip), or for a transport goes to the host as an ordinary call. Any other hook never reaches the host's call, in calls or not."
},
"reason": {
"type": "string",
"maxLength": 30000,
"maxGraphemes": 3000
},
"combine": {
"type": "string",
"knownValues": [
"all-allow"
],
"description": "all-allow: any number of routes, each answering a com.publicdomainrelay.temp.market.evaluatePolicy verdict; they run in edge order and the first that does not allow is the answer (errors are denies), else {allow: true, violations: []}. Absent: at most one route."
},
"default": {
"type": "string",
"maxLength": 512,
"description": "A module (rkey of the same publisher's com.fedfork.exec.wasm.module, or a local key) that serves the hook when nothing routes it, at the entry its implements names, on its own calls allowlist (never the caller's call); a default whose module lists no calls is refused. A pinned module's default comes only from where it is pinned (a lockfile, a pinned composition instance)."
}
}
},
"implementation": {
"type": "object",
"required": [
"nsid",
"entry"
],
"properties": {
"nsid": {
"type": "string",
"format": "nsid"
},
"entry": {
"type": "string",
"maxLength": 256
}
}
},
"didkey": {
"type": "object",
"required": [
"services"
],
"properties": {
"services": {
"type": "array",
"maxLength": 64,
"description": "https origins whose request calls carry a service-auth token the did:key mints (the fedproxy ingress relay).",
"items": {
"type": "string",
"format": "uri"
}
}
}
},
"action": {
"type": "object",
"required": [
"entry",
"label"
],
"properties": {
"entry": {
"type": "string",
"maxLength": 256
},
"label": {
"type": "string",
"maxLength": 2560,
"maxGraphemes": 256
},
"description": {
"type": "string",
"maxLength": 30000,
"maxGraphemes": 3000
},
"readOnly": {
"type": "boolean",
"description": "The entry changes none of the user's data: a host may run it without asking (an MCP tool's readOnlyHint). Absent: a write, which a host confirms with the user. Not part of the module's pin: a host's own config may override it."
},
"fields": {
"type": "array",
"maxLength": 256,
"description": "Inputs the user (or an MCP client) supplies; each key becomes a property of the module input.",
"items": {
"type": "ref",
"ref": "#field"
}
}
}
},
"field": {
"type": "object",
"required": [
"key",
"label"
],
"properties": {
"key": {
"type": "string",
"maxLength": 256
},
"label": {
"type": "string",
"maxLength": 2560,
"maxGraphemes": 256
},
"type": {
"type": "string",
"knownValues": ["string", "integer", "number", "boolean", "object", "array"],
"default": "string",
"description": "The JSON Schema type of the value (an MCP tool's inputSchema); an MCP host coerces an argument to it, or refuses the call."
},
"required": {
"type": "boolean",
"description": "An MCP host refuses a call without it before the module runs."
},
"description": {
"type": "string",
"maxLength": 30000,
"maxGraphemes": 3000,
"description": "What the value is, for a form's hint or an MCP tool's input description (default: the label)."
}
}
}
}
}