@dcasegr/skein 0.0.0-stage → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +525 -2
  2. package/bin/skein-host.js +22 -0
  3. package/bin/skein.js +8 -0
  4. package/dist/client/admin-cli.d.ts +10 -0
  5. package/dist/client/admin-cli.js +370 -0
  6. package/dist/client/admin.d.ts +139 -0
  7. package/dist/client/admin.js +256 -0
  8. package/dist/client/bundle.d.ts +9 -0
  9. package/dist/client/bundle.js +34 -0
  10. package/dist/client/cli.d.ts +44 -0
  11. package/dist/client/cli.js +306 -0
  12. package/dist/client/client.d.ts +161 -0
  13. package/dist/client/client.js +237 -0
  14. package/dist/client/config.d.ts +18 -0
  15. package/dist/client/config.js +31 -0
  16. package/dist/client/conversation.d.ts +62 -0
  17. package/dist/client/conversation.js +113 -0
  18. package/dist/client/raw.d.ts +94 -0
  19. package/dist/client/raw.js +154 -0
  20. package/dist/client/target.d.ts +34 -0
  21. package/dist/client/target.js +158 -0
  22. package/dist/dev/cli.d.ts +8 -0
  23. package/dist/dev/cli.js +248 -0
  24. package/dist/dev/scan.d.ts +15 -0
  25. package/dist/dev/scan.js +173 -0
  26. package/dist/envelope-cbor.d.ts +110 -0
  27. package/dist/envelope-cbor.js +160 -0
  28. package/dist/envelope.d.ts +38 -0
  29. package/dist/envelope.js +101 -0
  30. package/dist/host/arc.d.ts +131 -0
  31. package/dist/host/arc.js +425 -0
  32. package/dist/host/billing.d.ts +102 -0
  33. package/dist/host/billing.js +167 -0
  34. package/dist/host/boot.d.ts +246 -0
  35. package/dist/host/boot.js +643 -0
  36. package/dist/host/cli.d.ts +57 -0
  37. package/dist/host/cli.js +1253 -0
  38. package/dist/host/clock.d.ts +3 -0
  39. package/dist/host/clock.js +8 -0
  40. package/dist/host/control.d.ts +45 -0
  41. package/dist/host/control.js +170 -0
  42. package/dist/host/cron.d.ts +99 -0
  43. package/dist/host/cron.js +196 -0
  44. package/dist/host/deliver.d.ts +53 -0
  45. package/dist/host/deliver.js +251 -0
  46. package/dist/host/deploy.d.ts +29 -0
  47. package/dist/host/deploy.js +55 -0
  48. package/dist/host/door-answer.d.ts +24 -0
  49. package/dist/host/door-answer.js +21 -0
  50. package/dist/host/events.d.ts +89 -0
  51. package/dist/host/events.js +222 -0
  52. package/dist/host/fake-arcade.d.ts +40 -0
  53. package/dist/host/fake-arcade.js +149 -0
  54. package/dist/host/fake-discovery.d.ts +4 -0
  55. package/dist/host/fake-discovery.js +58 -0
  56. package/dist/host/feeds.d.ts +127 -0
  57. package/dist/host/feeds.js +422 -0
  58. package/dist/host/frontdoor.d.ts +92 -0
  59. package/dist/host/frontdoor.js +172 -0
  60. package/dist/host/genesis.d.ts +259 -0
  61. package/dist/host/genesis.js +353 -0
  62. package/dist/host/handles.d.ts +40 -0
  63. package/dist/host/handles.js +88 -0
  64. package/dist/host/hostenv.d.ts +30 -0
  65. package/dist/host/hostenv.js +83 -0
  66. package/dist/host/image-chain.d.ts +127 -0
  67. package/dist/host/image-chain.js +440 -0
  68. package/dist/host/install.d.ts +22 -0
  69. package/dist/host/install.js +139 -0
  70. package/dist/host/instances.d.ts +227 -0
  71. package/dist/host/instances.js +430 -0
  72. package/dist/host/kernel.d.ts +246 -0
  73. package/dist/host/kernel.js +603 -0
  74. package/dist/host/liveness.d.ts +65 -0
  75. package/dist/host/liveness.js +155 -0
  76. package/dist/host/manifest.d.ts +160 -0
  77. package/dist/host/manifest.js +597 -0
  78. package/dist/host/p2p.d.ts +337 -0
  79. package/dist/host/p2p.js +1002 -0
  80. package/dist/host/packet.d.ts +121 -0
  81. package/dist/host/packet.js +562 -0
  82. package/dist/host/plan.d.ts +154 -0
  83. package/dist/host/plan.js +418 -0
  84. package/dist/host/providers.d.ts +238 -0
  85. package/dist/host/providers.js +565 -0
  86. package/dist/host/roster.d.ts +72 -0
  87. package/dist/host/roster.js +172 -0
  88. package/dist/host/router.d.ts +782 -0
  89. package/dist/host/router.js +2411 -0
  90. package/dist/host/signer.d.ts +49 -0
  91. package/dist/host/signer.js +167 -0
  92. package/dist/host/store-sqlite.d.ts +39 -0
  93. package/dist/host/store-sqlite.js +170 -0
  94. package/dist/host/stores.d.ts +43 -0
  95. package/dist/host/stores.js +342 -0
  96. package/dist/host/sync.d.ts +121 -0
  97. package/dist/host/sync.js +467 -0
  98. package/dist/host/testbeef.d.ts +21 -0
  99. package/dist/host/testbeef.js +37 -0
  100. package/dist/host/testhost.d.ts +149 -0
  101. package/dist/host/testhost.js +211 -0
  102. package/dist/host/vcdiff.d.ts +9 -0
  103. package/dist/host/vcdiff.js +210 -0
  104. package/dist/host/wasm-kernel.d.ts +87 -0
  105. package/dist/host/wasm-kernel.js +296 -0
  106. package/dist/host/wasm-worker.d.ts +1 -0
  107. package/dist/host/wasm-worker.js +186 -0
  108. package/dist/peers/cron.d.ts +33 -0
  109. package/dist/peers/cron.js +75 -0
  110. package/dist/peers/infer-main.d.ts +2 -0
  111. package/dist/peers/infer-main.js +74 -0
  112. package/dist/peers/infer.d.ts +163 -0
  113. package/dist/peers/infer.js +367 -0
  114. package/dist/runtime/beef.d.ts +28 -0
  115. package/dist/runtime/beef.js +107 -0
  116. package/dist/runtime/bitcoin.d.ts +36 -0
  117. package/dist/runtime/bitcoin.js +141 -0
  118. package/dist/runtime/cid.d.ts +14 -0
  119. package/dist/runtime/cid.js +51 -0
  120. package/dist/runtime/dispatch.d.ts +92 -0
  121. package/dist/runtime/dispatch.js +142 -0
  122. package/dist/runtime/envelope.d.ts +60 -0
  123. package/dist/runtime/envelope.js +101 -0
  124. package/dist/runtime/heads.d.ts +25 -0
  125. package/dist/runtime/heads.js +37 -0
  126. package/dist/runtime/identity.d.ts +28 -0
  127. package/dist/runtime/identity.js +67 -0
  128. package/dist/runtime/index-store.d.ts +152 -0
  129. package/dist/runtime/index-store.js +715 -0
  130. package/dist/runtime/log.d.ts +62 -0
  131. package/dist/runtime/log.js +104 -0
  132. package/dist/runtime/programs.d.ts +30 -0
  133. package/dist/runtime/programs.js +61 -0
  134. package/dist/runtime/records.d.ts +135 -0
  135. package/dist/runtime/records.js +149 -0
  136. package/dist/runtime/sqlite.d.ts +33 -0
  137. package/dist/runtime/sqlite.js +604 -0
  138. package/dist/runtime/store.d.ts +141 -0
  139. package/dist/runtime/store.js +24 -0
  140. package/dist/runtime/syscalls.d.ts +9 -0
  141. package/dist/runtime/syscalls.js +41 -0
  142. package/dist/runtime/tree.d.ts +60 -0
  143. package/dist/runtime/tree.js +196 -0
  144. package/dist/runtime/types.d.ts +100 -0
  145. package/dist/runtime/types.js +7 -0
  146. package/dist/testapps.d.ts +101 -0
  147. package/dist/testapps.js +275 -0
  148. package/dist/testkit.d.ts +25 -0
  149. package/dist/testkit.js +48 -0
  150. package/dist/wallet.d.ts +35 -0
  151. package/dist/wallet.js +87 -0
  152. package/images/README.md +68 -0
  153. package/images/default/README.md +38 -0
  154. package/images/default/bin/frontdoor.cid +1 -0
  155. package/images/default/bin/frontdoor.json +5 -0
  156. package/images/default/bin/messagebox.cid +1 -0
  157. package/images/default/bin/messagebox.json +8 -0
  158. package/images/default/bin/wallet.cid +1 -0
  159. package/images/default/bin/wallet.json +14 -0
  160. package/images/default/etc/config.json +1 -0
  161. package/images/default/etc/dispatch.json +82 -0
  162. package/images/host/etc/apps.json +8 -0
  163. package/kernel-zig/README.md +1247 -0
  164. package/kernel-zig/web/client.js +65 -0
  165. package/kernel-zig/web/kernel.d.ts +59 -0
  166. package/kernel-zig/web/kernel.js +329 -0
  167. package/kernel-zig/web/store.js +67 -0
  168. package/kernel-zig/web/worker.js +79 -0
  169. package/kernel-zig/zig-out/web/skein-kernel.wasm +0 -0
  170. package/package.json +77 -4
  171. package/wasm/README.md +35 -0
  172. package/wasm/frontdoor.wasm +0 -0
  173. package/wasm/messagebox.wasm +0 -0
  174. package/wasm/resolve.wasm +0 -0
  175. package/wasm/wallet.wasm +0 -0
  176. package/wasm/wire-probe.wasm +0 -0
@@ -0,0 +1,155 @@
1
+ // The liveness tool (#138): a runtime handler keyed by event name, like the
2
+ // deadline, fetch and beacon handlers (#126). An app's installed program
3
+ // declares, once per topic,
4
+ //
5
+ // liveness {event: "liveness", topic, window: <ms, a second to a day>}
6
+ // unliveness {event: "unliveness", topic}
7
+ //
8
+ // and the kernel records it on the step's update (kernel-zig/src/
9
+ // subscriptions.zig livenessProblem / livenessFold). Here, for each liveness
10
+ // topic the apps keep (folded from the log, livenessOf, then followed live):
11
+ //
12
+ // - the instance's own libp2p node subscribes the topic WITHOUT admitting
13
+ // its messages: no front-door call, no entry, nothing logged (P2PHost:
14
+ // a topic only liveness takes is judged here alone);
15
+ // - each message is a beacon beat (p2p.ts beaconFrame: {body, at, sender,
16
+ // signature}); its instance signature is checked (beaconBeat) and a beat
17
+ // that does not verify is dropped (and rejected to GossipSub);
18
+ // - the beats newer than the window are kept, the latest per sender
19
+ // (identity key), with the peer that published it (`from`); the node's
20
+ // OWN beats on the topic are written into the same set (gossip does not
21
+ // echo them: P2PHost.beacons);
22
+ // - in memory only: empty after a restart until the next beats; dropped at
23
+ // the app's unliveness or uninstall.
24
+ //
25
+ // The set is served to the app's page by the host itself, no program in
26
+ // between (Router: GET /<app>/.live/<topic> on the instance's origin).
27
+ // A runtime without this tool records the events and nothing happens.
28
+ import { beaconBeat, emittedEvents, isTopic } from "./p2p.js";
29
+ /** A window's bounds (ms): a second, a day (subscriptions.zig LIVENESS_MIN_MS / _MAX_MS). */
30
+ export const LIVENESS_MIN_MS = 1000;
31
+ export const LIVENESS_MAX_MS = 86_400_000;
32
+ /** A `liveness` / `unliveness` event record, read (subscriptions.zig livenessEventOf); or why it is not one this host follows. */
33
+ export function livenessEvent(rec) {
34
+ const event = rec.event;
35
+ if (rec.kind !== "event" || (event !== "liveness" && event !== "unliveness"))
36
+ return { refused: "not a liveness or unliveness event" };
37
+ if (typeof rec.app !== "string" || !rec.app)
38
+ return { refused: "it names no app (its program record is not installed): ignored" };
39
+ if (!isTopic(rec.topic))
40
+ return { refused: `${JSON.stringify(rec.topic)} is not a topic` };
41
+ if (event === "unliveness")
42
+ return { event, app: rec.app, topic: rec.topic };
43
+ const window = typeof rec.window === "number" ? rec.window : typeof rec.window === "bigint" ? Number(rec.window) : NaN;
44
+ if (!Number.isInteger(window) || window < LIVENESS_MIN_MS || window > LIVENESS_MAX_MS)
45
+ return { refused: "a liveness window is from a second to a day (`window`, ms)" };
46
+ return { event, live: { app: rec.app, topic: rec.topic, window } };
47
+ }
48
+ /** Fold liveness events in order: a liveness replaces the app's own on the topic, an unliveness removes it. */
49
+ export function foldLiveness(events, into = []) {
50
+ for (const e of events) {
51
+ const [app, topic] = e.event === "liveness" ? [e.live.app, e.live.topic] : [e.app, e.topic];
52
+ const i = into.findIndex((l) => l.app === app && l.topic === topic);
53
+ if (e.event === "liveness") {
54
+ if (i >= 0)
55
+ into[i] = e.live;
56
+ else
57
+ into.push(e.live);
58
+ }
59
+ else if (i >= 0)
60
+ into.splice(i, 1);
61
+ }
62
+ return into;
63
+ }
64
+ /** The liveness standing, folded from the store's log as the subscriptions and beacons are (p2p.ts subscriptionsOf). Read only. */
65
+ export async function livenessOf(store) {
66
+ return foldLiveness(await emittedEvents(store, (rec) => { const e = livenessEvent(rec); return "refused" in e ? undefined : e; }));
67
+ }
68
+ /** The tool's state: per instance, the apps' liveness and the beats kept per topic (in memory). */
69
+ export class Liveness {
70
+ lives = new Map();
71
+ /** handle → topic → sender → the latest beat. */
72
+ beats = new Map();
73
+ now;
74
+ /** Told each beat newly kept (shruggr/skein#150: the overlay's sync reads a peer's tip anchor from it). */
75
+ kept;
76
+ constructor(now = Date.now) { this.now = now; }
77
+ /** `handle`'s apps keep this liveness now: the beats of topics none keeps any more are dropped. */
78
+ set(handle, lives) {
79
+ if (!lives.length) {
80
+ this.drop(handle);
81
+ return;
82
+ }
83
+ this.lives.set(handle, lives.map((l) => ({ ...l })));
84
+ const kept = this.beats.get(handle);
85
+ if (kept)
86
+ for (const t of kept.keys())
87
+ if (!lives.some((l) => l.topic === t))
88
+ kept.delete(t);
89
+ }
90
+ /** The topics `handle`'s apps keep liveness for (each once). */
91
+ topics(handle) { return [...new Set((this.lives.get(handle) ?? []).map((l) => l.topic))]; }
92
+ /** Whether an app of `handle` keeps liveness for `topic`. */
93
+ takes(handle, topic) { return (this.lives.get(handle) ?? []).some((l) => l.topic === topic); }
94
+ /** The longest window on `topic` among `handle`'s apps (ms), or undefined. */
95
+ windowOf(handle, topic) {
96
+ const ws = (this.lives.get(handle) ?? []).filter((l) => l.topic === topic).map((l) => l.window);
97
+ return ws.length ? Math.max(...ws) : undefined;
98
+ }
99
+ /**
100
+ * A message on `topic` at `handle`'s node, published by peer `from`: kept when it is a beat whose
101
+ * instance signature verifies (beaconBeat) and is newer than the longest window on the topic — the
102
+ * sender's latest replaces an older one. Nothing logged.
103
+ */
104
+ observe(handle, topic, frame, from) {
105
+ const window = this.windowOf(handle, topic);
106
+ if (window === undefined)
107
+ return "ignore";
108
+ const b = beaconBeat(topic, frame);
109
+ if ("problem" in b)
110
+ return "reject";
111
+ const now = this.now();
112
+ // A beat older than the window is not live; one dated more than a window ahead of this clock is not believed.
113
+ if (now - b.at >= window || b.at - now > window)
114
+ return "ignore";
115
+ let byTopic = this.beats.get(handle);
116
+ if (!byTopic)
117
+ this.beats.set(handle, byTopic = new Map());
118
+ let bySender = byTopic.get(topic);
119
+ if (!bySender)
120
+ byTopic.set(topic, bySender = new Map());
121
+ const sender = Buffer.from(b.sender).toString("hex");
122
+ const was = bySender.get(sender);
123
+ if (!was || b.at > was.at) {
124
+ const beat = { sender, at: b.at, body: b.body, from };
125
+ bySender.set(sender, beat);
126
+ this.kept?.(handle, topic, beat);
127
+ }
128
+ // The stale ones go as the set is touched.
129
+ for (const [k, x] of bySender)
130
+ if (now - x.at >= window)
131
+ bySender.delete(k);
132
+ return "accept";
133
+ }
134
+ /** The beats live for `app`'s liveness on `topic` (newer than its window), newest first; undefined: the app keeps no liveness for the topic. */
135
+ read(handle, app, topic) {
136
+ const l = (this.lives.get(handle) ?? []).find((x) => x.app === app && x.topic === topic);
137
+ if (!l)
138
+ return undefined;
139
+ const now = this.now();
140
+ return [...(this.beats.get(handle)?.get(topic)?.values() ?? [])].filter((b) => now - b.at < l.window).sort((x, y) => y.at - x.at);
141
+ }
142
+ /** Every beat live on `topic` at `handle` (newer than the longest window on it), whichever app keeps it. */
143
+ live(handle, topic) {
144
+ const window = this.windowOf(handle, topic);
145
+ if (window === undefined)
146
+ return [];
147
+ const now = this.now();
148
+ return [...(this.beats.get(handle)?.get(topic)?.values() ?? [])].filter((b) => now - b.at < window);
149
+ }
150
+ /** Forget `handle`: its liveness and its beats. */
151
+ drop(handle) {
152
+ this.lives.delete(handle);
153
+ this.beats.delete(handle);
154
+ }
155
+ }
@@ -0,0 +1,160 @@
1
+ export type RouteTransport = "mailbox" | "event" | "http" | "libp2p";
2
+ /** A route as the manifest writes it (#143). */
3
+ export interface RouteIn {
4
+ transport?: RouteTransport;
5
+ address: string;
6
+ prefix?: true;
7
+ filters?: string[];
8
+ handler?: string;
9
+ [setting: string]: unknown;
10
+ }
11
+ export interface FunctionDecl {
12
+ writes: boolean;
13
+ args?: unknown;
14
+ answer?: unknown;
15
+ }
16
+ export interface Provide {
17
+ interface: string;
18
+ functions: Record<string, FunctionDecl>;
19
+ }
20
+ export interface Manifest {
21
+ kind: "app";
22
+ name: string;
23
+ version: string;
24
+ programs: Record<string, string | Record<string, unknown>>;
25
+ routes?: RouteIn[];
26
+ filters?: Record<string, string>;
27
+ roles?: Record<string, string[]>;
28
+ config?: Record<string, unknown>;
29
+ provides?: Provide[];
30
+ requires?: string[];
31
+ start?: {
32
+ body: Record<string, unknown>;
33
+ };
34
+ stop?: {
35
+ body: Record<string, unknown>;
36
+ };
37
+ description?: string;
38
+ }
39
+ /** A shell program's support for one command (#25, #83): files mounted read-only at `mount` for that command only, env defaults. */
40
+ export interface ShellSupport {
41
+ mount: string;
42
+ files: Record<string, string>;
43
+ env: Record<string, string>;
44
+ }
45
+ /** A shell program as the manifest names it (#83): its modules and support files, paths in the tree. */
46
+ export interface ShellSource {
47
+ kind: "shell";
48
+ modules: Record<string, string>;
49
+ support: Record<string, ShellSupport>;
50
+ description?: string;
51
+ }
52
+ /** Where a role's program comes from. */
53
+ export type ProgramSource = {
54
+ kind: "wasm" | "cid";
55
+ path: string;
56
+ name: string;
57
+ } | {
58
+ kind: "instance";
59
+ name: string;
60
+ } | ShellSource;
61
+ /** A route normalised: transport set; the address, filters and handler as written. */
62
+ export type Route = RouteIn & {
63
+ transport: RouteTransport;
64
+ };
65
+ /** A manifest checked: the fields as installed. */
66
+ export interface Checked {
67
+ manifest: Omit<Manifest, "routes"> & {
68
+ routes: Route[];
69
+ provides: Provide[];
70
+ requires: string[];
71
+ };
72
+ sources: Record<string, ProgramSource>;
73
+ /** What `config.overlay` added (APPS.md §6): route keys (routeKey). */
74
+ derived: Derived;
75
+ }
76
+ export declare class ManifestError extends Error {
77
+ readonly problems: string[];
78
+ constructor(problems: string[]);
79
+ }
80
+ export declare const RESERVED_NAMES: string[];
81
+ /** Why `shape` is not a shape (APPS.md §2), or undefined. */
82
+ export declare function shapeProblem(shape: unknown, at: string): string | undefined;
83
+ /**
84
+ * An http route's path as served: relative to /<app>/ (a leading "/" too). Throws
85
+ * on anything that could name a path outside that prefix.
86
+ */
87
+ export declare function appPath(app: string, p: string): string;
88
+ /**
89
+ * A box as the kernel's table holds it (#128): relative to the app, as an http
90
+ * path is — "" or the app's own name is the app's box `<app>`; "x" is `<app>/x`. Throws on a
91
+ * box that is not one: an empty, "." or ".." segment (a leading, trailing or doubled "/"),
92
+ * whitespace or a control character, or more than 128 bytes resolved (the messagebox
93
+ * server's limit).
94
+ */
95
+ export declare function appBox(app: string, b: string): string;
96
+ /** A route's address as served: an http path under /<app>/ (appPath); a box under the app's (appBox); a libp2p name as written. */
97
+ export declare function rowAddress(app: string, r: {
98
+ transport: string;
99
+ address: string;
100
+ }): string;
101
+ /** A route's key as the kernel's table knows it (dispatch.ts rowKey): `<transport> <address as served>[ prefix]`. */
102
+ export declare function routeKey(app: string, r: {
103
+ transport: string;
104
+ address: string;
105
+ prefix?: boolean;
106
+ }): string;
107
+ /**
108
+ * A handler (or a declared filter's function) resolved against the app's programs (#143):
109
+ * "<role>.<fn>"; a bare name that is a role — the program, no function named; any other bare name
110
+ * — a function of the app's one program. Undefined: none of these.
111
+ */
112
+ export declare function handlerOf(h: unknown, roles: string[]): {
113
+ role: string;
114
+ fn?: string;
115
+ } | undefined;
116
+ /** A route's filter as the kernel's table names it (#143): the kernel's; an own filter's name → `<app>.<name>`; another app's as written. */
117
+ export declare const filterRef: (app: string, f: string) => string;
118
+ /** Check and normalise a manifest. `has(path)`: whether the tree has a file at the path. */
119
+ export declare function checkManifest(json: unknown, has: (path: string) => boolean): Checked;
120
+ /**
121
+ * A shell program as the manifest names it (#83), checked: `code: "shell"`;
122
+ * `modules` command → bin/<x>.wasm in the tree, brush and coreutils among
123
+ * them (every other name a command the shell runs; two names may share a
124
+ * module: `node` is qjs); `support` per command of `modules`: an absolute
125
+ * `mount`, `files` (path under the mount → a file in the tree), `env` text →
126
+ * text. The install turns it into the record the kernel's shell runs.
127
+ */
128
+ export declare function shellSource(p: Record<string, unknown>, has: (path: string) => boolean, at: string): ShellSource | string[];
129
+ /** The role of an overlay app's engine (its `config.overlay` is the engine's). */
130
+ export declare const OVERLAY_ROLE = "overlay";
131
+ /** What the install derived from `config.overlay` (route keys), for the prompt. */
132
+ export interface Derived {
133
+ routes: string[];
134
+ }
135
+ /** An overlay app's wiring. */
136
+ export interface OverlayWiring {
137
+ routes: Route[];
138
+ topics: string[];
139
+ }
140
+ /**
141
+ * The wiring `config.overlay` asks for (APPS.md §6, #79, #143), or its problems. For each topic:
142
+ * the libp2p routes `<topic>` → submit (kernel.beef), `<topic>-admit` → peerAdmit, `<topic>-proof`
143
+ * → peerProof; the http route `/submit` (kernel.beef: a submission validates itself — #135, signed
144
+ * or validated) and `/lookup` (BRC-24's POST: answered by the engine's `lookup`, a filter — a read
145
+ * route, nothing logged); and the app's own box twice: an `event` route (what its libp2p routes
146
+ * admit — a gossiped submission, a peer's admit) and a `mailbox` route (its own watch of a
147
+ * submission the chain app has accepted, sent by the host's loopback). All to the role `overlay`,
148
+ * the engine, which the manifest must declare `lookup` a filter of. No `chain` or `status` box (the
149
+ * chain app's): the engine writes `<app>/…` only. No topics is accepted: the box routes, `/submit`
150
+ * and `/lookup` and no per-topic routes — the topics registered at runtime get theirs from the
151
+ * engine (#120). `market` ({window: <ms>}), `validator` ({every: <ms>}) and `terms` (a map, the
152
+ * beat's initial terms: skein-overlay 0.17.0) are the engine's own settings, read from the app record:
153
+ * checked, no routes derived. A field other than these is
154
+ * refused (no prefix declarations, #120). `isRole` tells which roles the manifest has.
155
+ */
156
+ export declare function overlayWiring(app: string, ov: unknown, isRole: (role: string) => boolean): OverlayWiring | string[];
157
+ /** The interfaces `requires` names that no installed app provides. */
158
+ export declare function missingInterfaces(requires: string[], installed: Array<{
159
+ provides?: Provide[];
160
+ }>): string[];