@jr2/orchestrator 0.2.1 → 0.4.1
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.
- package/bin/server.ts +7 -4
- package/console/canvas.ts +27 -14
- package/console/components/app.ts +10 -1
- package/console/components/fleet.ts +39 -6
- package/console/components/machine-pane.ts +89 -2
- package/console/components/nav.ts +1 -1
- package/console/components/schema-form.ts +12 -4
- package/console/json-field.ts +23 -0
- package/console/main.ts +110 -39
- package/console/store.ts +221 -17
- package/console/style.css +90 -0
- package/package.json +4 -5
- package/src/actor.ts +507 -54
- package/src/agent.ts +2 -2
- package/src/ambient.ts +2 -0
- package/src/assembly-checks.ts +165 -0
- package/src/assembly-tar.ts +494 -0
- package/src/assembly.ts +721 -0
- package/src/chart.ts +2050 -0
- package/src/charts.ts +720 -0
- package/src/config.ts +233 -22
- package/src/content-hash.ts +105 -0
- package/src/custodian.lua +313 -0
- package/src/custodian.ts +951 -0
- package/src/customize.ts +216 -25
- package/src/effect-checks.ts +557 -0
- package/src/effect.ts +905 -0
- package/src/effector-wire.ts +525 -0
- package/src/fingerprint.ts +4 -3
- package/src/gate.ts +8 -0
- package/src/git-clone.ts +65 -0
- package/src/git-push.ts +336 -0
- package/src/harness-client.ts +247 -25
- package/src/held-secrets.ts +643 -0
- package/src/holds.ts +156 -0
- package/src/http-effect.ts +981 -0
- package/src/http.ts +514 -119
- package/src/images.ts +58 -31
- package/src/index.ts +49 -4
- package/src/instance.ts +445 -59
- package/src/kube-client.ts +333 -0
- package/src/machine-doc.ts +88 -6
- package/src/model-keys.ts +92 -0
- package/src/mount-digest.ts +53 -0
- package/src/names.ts +89 -7
- package/src/notices.ts +88 -0
- package/src/open-body.ts +1444 -0
- package/src/open-effect.ts +144 -0
- package/src/open.ts +4 -4
- package/src/parts.ts +530 -33
- package/src/party.ts +468 -0
- package/src/pick.ts +309 -0
- package/src/pool.ts +1 -1
- package/src/registration.ts +301 -17
- package/src/repo-fetch.ts +61 -86
- package/src/repos.ts +63 -74
- package/src/rest.ts +133 -0
- package/src/run-host.ts +1841 -105
- package/src/sandbox-effect.ts +891 -0
- package/src/sandbox-effector.ts +111 -0
- package/src/sandbox-kube.ts +1719 -0
- package/src/sandbox-watch.ts +260 -0
- package/src/secret-placement.ts +494 -0
- package/src/server.ts +285 -89
- package/src/setup.ts +589 -70
- package/src/size.ts +342 -0
- package/src/snapshot-store.ts +64 -13
- package/src/stub-harness.ts +5 -0
- package/src/sync-client.ts +54 -0
- package/src/timers.ts +178 -0
- package/src/tokens.ts +44 -12
- package/src/vocabulary.ts +66 -1
- package/src/wire.ts +156 -2
- package/src/workspace.ts +529 -194
- package/src/sandbox-kubectl.ts +0 -1144
package/src/images.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// The resolved key→ref image map, from the READ side (ADR-0037/0038/0049). `jr2 up` builds every
|
|
2
2
|
// image it deploys and writes this map into the `jr2-images` ConfigMap; the Sandbox port consults it
|
|
3
3
|
// when it creates a pod. This module is the shape both sides agree on — deliberately its own file,
|
|
4
|
-
// not folded into sandbox-
|
|
4
|
+
// not folded into sandbox-kube.ts, because the CLI needs the type without dragging in the
|
|
5
5
|
// kubectl port.
|
|
6
6
|
//
|
|
7
|
-
// The map is NESTED, never flat. The kit's own `harness
|
|
7
|
+
// The map is NESTED, never flat. The kit's own `harness` and the `custodian` sit beside a `sandbox`
|
|
8
8
|
// sub-map, so a user image can never shadow them — and `default` is the one reserved key in that
|
|
9
9
|
// sub-map, because ADR-0037's fallback chain is built on it.
|
|
10
10
|
//
|
|
11
11
|
// A user image's key is its build context's CONTENT DIGEST (ADR-0049). That is what lets the two
|
|
12
12
|
// sides agree without a path table: a Machine names its context as a `file:` URL, whose absolute
|
|
13
|
-
// path differs between the host at `jr2 up` and the
|
|
14
|
-
// folder — the
|
|
13
|
+
// path differs between the host at `jr2 up` and the Orchestrator Kit image, while the FOLDER is the
|
|
14
|
+
// same folder — the published Assembly's `node_modules` holds the very tree the converge hashed. Digest in, digest
|
|
15
15
|
// out, no dirname registry in between.
|
|
16
16
|
//
|
|
17
17
|
// There is NO cache and NO memo for the map itself. The whole reason it arrives as a mounted
|
|
@@ -24,10 +24,12 @@ import { createHash } from "node:crypto";
|
|
|
24
24
|
import { readdir, readFile } from "node:fs/promises";
|
|
25
25
|
import { join, relative } from "node:path";
|
|
26
26
|
import { fileURLToPath } from "node:url";
|
|
27
|
+
import { byteOrder } from "./content-hash.ts";
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
* Every image ref one converge resolved. `harness
|
|
30
|
-
*
|
|
30
|
+
* Every image ref one converge resolved. `harness` is the kit's own (built from a kit checkout, or
|
|
31
|
+
* the published `<kitversion>` tag); `custodian` is the pinned Envoy the kit deploys and never
|
|
32
|
+
* builds (ADR-0038, ADR-0059); `sandbox` is the instance's own docker-context
|
|
31
33
|
* builds — one `docker build` straight to a content tag, carrying no jr2 layers at all, because the
|
|
32
34
|
* Harness arrives at POD time on the `/opt/jr2` volume (ADR-0037).
|
|
33
35
|
*
|
|
@@ -38,9 +40,10 @@ import { fileURLToPath } from "node:url";
|
|
|
38
40
|
export type ImageRefs = {
|
|
39
41
|
/** The stock Harness image — also the last leg of the Sandbox Image fallback chain. */
|
|
40
42
|
harness: string;
|
|
41
|
-
/** The
|
|
43
|
+
/** The Custodian's image (ADR-0059) — upstream Envoy, pinned by digest, re-homed onto a
|
|
44
|
+
* `kitRegistry` when one is set. Every Harness pod runs one (it carries the Menu, ADR-0013), so
|
|
42
45
|
* this is required: a map without it fails the provision rather than shipping a mute pod. */
|
|
43
|
-
|
|
46
|
+
custodian: string;
|
|
44
47
|
/** Built Sandbox Images by their build context's CONTENT DIGEST (ADR-0049), plus the reserved
|
|
45
48
|
* key `default` — the Instance's `images/default`, ADR-0037's middle leg. Empty when the
|
|
46
49
|
* instance ships no context and scaffolded no default. */
|
|
@@ -99,10 +102,9 @@ export async function readImageRefs(path: string): Promise<ImageRefs> {
|
|
|
99
102
|
return value as string;
|
|
100
103
|
};
|
|
101
104
|
const harness = ref("harness");
|
|
102
|
-
// Required, not optional:
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
const adapter = ref("adapter");
|
|
105
|
+
// Required, not optional: an Agent whose pod has no Custodian parks forever on a Menu it cannot
|
|
106
|
+
// read (ADR-0013). Failing the provision is the only honest outcome.
|
|
107
|
+
const custodian = ref("custodian");
|
|
106
108
|
const sandboxRaw = map["sandbox"];
|
|
107
109
|
if (sandboxRaw !== undefined && (typeof sandboxRaw !== "object" || sandboxRaw === null || Array.isArray(sandboxRaw)))
|
|
108
110
|
bad("`sandbox` must be an object of name → ref");
|
|
@@ -121,7 +123,7 @@ export async function readImageRefs(path: string): Promise<ImageRefs> {
|
|
|
121
123
|
if (typeof value !== "string") bad(`\`sandboxUser.${name}\` is not a USER (got ${JSON.stringify(value)})`);
|
|
122
124
|
sandboxUser[name] = value as string;
|
|
123
125
|
}
|
|
124
|
-
return { harness,
|
|
126
|
+
return { harness, custodian, sandbox, sandboxUser };
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
/**
|
|
@@ -142,7 +144,8 @@ export function isImageContext(image: string): boolean {
|
|
|
142
144
|
* nothing else (ADR-0037/0038).
|
|
143
145
|
*
|
|
144
146
|
* It lives HERE, not in the CLI's build module, because BOTH sides compute it: `jr2 up` keys the
|
|
145
|
-
* map it publishes by this digest, and the
|
|
147
|
+
* map it publishes by this digest, and the Orchestrator computes it again at provision, over the
|
|
148
|
+
* published Assembly, to
|
|
146
149
|
* look the ref up. One implementation is what makes "the host and the pod agree without a path
|
|
147
150
|
* table" true rather than hopeful (ADR-0049).
|
|
148
151
|
*
|
|
@@ -155,12 +158,11 @@ export function isImageContext(image: string): boolean {
|
|
|
155
158
|
export async function imageContextDigest(dir: string): Promise<string> {
|
|
156
159
|
const h = createHash("sha256");
|
|
157
160
|
// A domain separator, and the whole of it: a Sandbox Image's build is `docker build` of the
|
|
158
|
-
// user's own directory with no generated text anywhere in it, so
|
|
159
|
-
//
|
|
160
|
-
// WITH. The constant only keeps this hash's domain apart from the bundle's.
|
|
161
|
+
// user's own directory with no generated text anywhere in it, so there is nothing to salt WITH.
|
|
162
|
+
// The constant only keeps this hash's domain apart from the Assembly's.
|
|
161
163
|
h.update("salt:sandbox\n");
|
|
162
164
|
const walk = async (root: string, d: string): Promise<void> => {
|
|
163
|
-
const entries = (await readdir(d, { withFileTypes: true })).sort((a, b) => a.name
|
|
165
|
+
const entries = (await readdir(d, { withFileTypes: true })).sort((a, b) => byteOrder(a.name, b.name));
|
|
164
166
|
for (const e of entries) {
|
|
165
167
|
const p = join(d, e.name);
|
|
166
168
|
if (e.isDirectory()) await walk(root, p);
|
|
@@ -181,7 +183,7 @@ export async function imageContextDigest(dir: string): Promise<string> {
|
|
|
181
183
|
* own key and is never looked up. Absent is the reserved `default` key — ADR-0037's middle leg.
|
|
182
184
|
*
|
|
183
185
|
* A context whose folder is unreadable fails HERE, before a Secret or a CR exists, naming the path:
|
|
184
|
-
* in a deployed Orchestrator that means the module shipped a context the
|
|
186
|
+
* in a deployed Orchestrator that means the module shipped a context the current Assembly does not
|
|
185
187
|
* hold, which is a packaging bug and not a cluster one.
|
|
186
188
|
*/
|
|
187
189
|
async function imageKey(image: string): Promise<string> {
|
|
@@ -193,7 +195,7 @@ async function imageKey(image: string): Promise<string> {
|
|
|
193
195
|
throw new Error(
|
|
194
196
|
`the Sandbox Image context ${image} cannot be read (${(err as NodeJS.ErrnoException).code ?? "read failed"}) — ` +
|
|
195
197
|
"a `file:` image names a docker context the Machine's own module ships (ADR-0037), so it must travel " +
|
|
196
|
-
`with the module: check that ${dir} exists in the
|
|
198
|
+
`with the module: check that ${dir} exists in the current Assembly.`,
|
|
197
199
|
);
|
|
198
200
|
}
|
|
199
201
|
}
|
|
@@ -226,13 +228,14 @@ export type ResolvedImage = {
|
|
|
226
228
|
* cannot prove is non-root because it does not read the image's `/etc/passwd`, and uid 0
|
|
227
229
|
* (`USER root`, `USER 0`), which plainly is root.
|
|
228
230
|
*
|
|
229
|
-
* Both surface as CreateContainerConfigError on the
|
|
231
|
+
* Both surface as CreateContainerConfigError on the init step that runs the image — the
|
|
230
232
|
* preflight — and that container never starts, so `kubectl logs -c preflight` prints nothing. The
|
|
231
233
|
* record is the one place that can see it coming: `docker inspect` at converge already put the
|
|
232
234
|
* string in the map, so the provision can fail BEFORE it applies anything. Only a BUILT image is
|
|
233
|
-
* knowable here; a registry ref was never inspected, so it answers undefined and that pod
|
|
234
|
-
*
|
|
235
|
-
*
|
|
235
|
+
* knowable here; a registry ref was never inspected, so it answers undefined and that pod runs
|
|
236
|
+
* out the provision's Ready budget, whose message names the numeric non-root `USER` among the
|
|
237
|
+
* floor's causes (sandbox-kube.ts). The Orchestrator reads no Pod (ADR-0063), so the kubelet's
|
|
238
|
+
* waiting reason is not visible to it.
|
|
236
239
|
*/
|
|
237
240
|
refusedUser?: string;
|
|
238
241
|
};
|
|
@@ -248,6 +251,14 @@ function judgeUser(recorded: string | undefined): Pick<ResolvedImage, "fallbackS
|
|
|
248
251
|
return { fallbackSeat: false };
|
|
249
252
|
}
|
|
250
253
|
|
|
254
|
+
/**
|
|
255
|
+
* The run a provision resolves images for, when it holds an Assembly that is not the current one
|
|
256
|
+
* (ADR-0069). The image map holds the current walk's contexts only, so a held run whose context the
|
|
257
|
+
* current Assembly dropped cannot provision, and `jr2 up` cannot fix it: the error must say which
|
|
258
|
+
* case it is.
|
|
259
|
+
*/
|
|
260
|
+
export type HeldImageScope = { runId: string; assembly: string; current: string | undefined };
|
|
261
|
+
|
|
251
262
|
/**
|
|
252
263
|
* Look one built key up in the map this converge wrote — for the Sandbox Image and the User
|
|
253
264
|
* Container alike, because ADR-0005 gives the User Container "the same resolution" deliberately.
|
|
@@ -255,15 +266,27 @@ function judgeUser(recorded: string | undefined): Pick<ResolvedImage, "fallbackS
|
|
|
255
266
|
* An unknown key throws: a converge-time check is impossible for a ref and unnecessary for a
|
|
256
267
|
* context (the walk built every one it found), so this fires when the Orchestrator's own
|
|
257
268
|
* `node_modules` holds a context the LAST converge did not build — a stale deployment. The error
|
|
258
|
-
* says exactly that, because "re-run `jr2 up`" is the
|
|
269
|
+
* says exactly that, because "re-run `jr2 up`" is the fix. It also fires for a run under a held
|
|
270
|
+
* Assembly (ADR-0069) whose context the current walk no longer carries, which `jr2 up` cannot fix.
|
|
271
|
+
* With `held`, the error names that case alone: the run, the held Assembly and the current one.
|
|
259
272
|
*/
|
|
260
|
-
function builtRef(refs: ImageRefs, key: string, image: string, what: string): string {
|
|
273
|
+
function builtRef(refs: ImageRefs, key: string, image: string, what: string, held?: HeldImageScope): string {
|
|
261
274
|
const ref = refs.sandbox[key];
|
|
262
275
|
if (ref === undefined) {
|
|
276
|
+
if (held) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`no ${what} for ${image} (context digest ${key}) — run ${held.runId} is under the held Assembly ` +
|
|
279
|
+
`${held.assembly}, whose context ${key} the current Assembly ${held.current ?? "(none)"} does not ` +
|
|
280
|
+
"carry. The image map holds the current Assembly's contexts only, so `jr2 up` does not fix this: " +
|
|
281
|
+
"publish an Assembly that names the context again, or cancel the run (ADR-0069).",
|
|
282
|
+
);
|
|
283
|
+
}
|
|
263
284
|
throw new Error(
|
|
264
285
|
`no ${what} for ${image} (context digest ${key}) — this instance's last converge built ` +
|
|
265
286
|
`${Object.keys(refs.sandbox).length} image(s), none of them this one. Re-run \`jr2 up\`: it walks the ` +
|
|
266
|
-
"registered Machines and builds every `file:` context they carry (ADR-0037/0049)."
|
|
287
|
+
"registered Machines and builds every `file:` context they carry (ADR-0037/0049). A run under a held " +
|
|
288
|
+
"Assembly (ADR-0069) whose context the current Assembly no longer carries is the one case it does not " +
|
|
289
|
+
"fix: the map holds the current walk's contexts only.",
|
|
267
290
|
);
|
|
268
291
|
}
|
|
269
292
|
return ref;
|
|
@@ -279,7 +302,11 @@ function builtRef(refs: ImageRefs, key: string, image: string, what: string): st
|
|
|
279
302
|
* look up and nothing to say about its tag discipline — the cluster pulls it, and nothing was
|
|
280
303
|
* inspected, so no seat fact is known.
|
|
281
304
|
*/
|
|
282
|
-
export async function resolveSandboxImage(
|
|
305
|
+
export async function resolveSandboxImage(
|
|
306
|
+
refs: ImageRefs,
|
|
307
|
+
image?: string,
|
|
308
|
+
held?: HeldImageScope,
|
|
309
|
+
): Promise<ResolvedImage> {
|
|
283
310
|
if (image === undefined) {
|
|
284
311
|
const ref = refs.sandbox["default"];
|
|
285
312
|
if (ref === undefined) return { ref: refs.harness, fallbackSeat: false };
|
|
@@ -287,7 +314,7 @@ export async function resolveSandboxImage(refs: ImageRefs, image?: string): Prom
|
|
|
287
314
|
}
|
|
288
315
|
if (!isImageContext(image)) return { ref: image, fallbackSeat: false };
|
|
289
316
|
const key = await imageKey(image);
|
|
290
|
-
return { ref: builtRef(refs, key, image, "Sandbox Image"), ...judgeUser(refs.sandboxUser?.[key]) };
|
|
317
|
+
return { ref: builtRef(refs, key, image, "Sandbox Image", held), ...judgeUser(refs.sandboxUser?.[key]) };
|
|
291
318
|
}
|
|
292
319
|
|
|
293
320
|
/**
|
|
@@ -297,7 +324,7 @@ export async function resolveSandboxImage(refs: ImageRefs, image?: string): Prom
|
|
|
297
324
|
* the one place ADR-0005 promises none. Its `USER` is not judged either: the seat carries no
|
|
298
325
|
* `securityContext` at all, so root is allowed there.
|
|
299
326
|
*/
|
|
300
|
-
export async function resolveUserImage(refs: ImageRefs, image: string): Promise<string> {
|
|
327
|
+
export async function resolveUserImage(refs: ImageRefs, image: string, held?: HeldImageScope): Promise<string> {
|
|
301
328
|
if (!isImageContext(image)) return image;
|
|
302
|
-
return builtRef(refs, await imageKey(image), image, "User Container image");
|
|
329
|
+
return builtRef(refs, await imageKey(image), image, "User Container image", held);
|
|
303
330
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,20 +2,42 @@
|
|
|
2
2
|
// delivery surfaces, the duplex Actor over the Harness wire, and durable snapshot persistence
|
|
3
3
|
// (ADR-0002/0006/0007). Builds on the `@jr2/agent-protocol` wire contract.
|
|
4
4
|
//
|
|
5
|
-
// It does NOT speak MCP (ADR-0013): the
|
|
6
|
-
//
|
|
5
|
+
// It does NOT speak MCP (ADR-0013): the Harness presents the Menu to its model itself, and reaches
|
|
6
|
+
// the surface here through the Custodian in its pod. What lives here is the registration table and
|
|
7
|
+
// two thin HTTP adapters over it — plus what composes a Custodian (ADR-0059).
|
|
7
8
|
|
|
8
9
|
// The wire contract, re-exported: a workflow authors against ONE package (`defineEvent`,
|
|
9
10
|
// `jr2Setup`, `workspace`, … all import from "@jr2/orchestrator" — ADR-0015).
|
|
10
11
|
export * from "@jr2/agent-protocol";
|
|
11
12
|
export * from "./agent.ts";
|
|
13
|
+
// The Effect surface (ADR-0067): `command` itself is the wire-bound one, from harness-client.ts;
|
|
14
|
+
// `fromPick`, `paramsOf` and `answer` are what an author writes between a pick and its work.
|
|
15
|
+
export * from "./effect.ts";
|
|
16
|
+
// The http kind (ADR-0068): `http`, `secret`, `bearer`, `basic`, `text`, and the Effector's wire.
|
|
17
|
+
export * from "./http-effect.ts";
|
|
18
|
+
export * from "./sandbox-effect.ts";
|
|
19
|
+
// An Effect's Open parts (ADR-0054): the types `customize({ effects })` reads.
|
|
20
|
+
export type { EffectBinding, OpenEffect, OpenEffectPart } from "./open-effect.ts";
|
|
21
|
+
export { openPartsText } from "./open-effect.ts";
|
|
22
|
+
export * from "./effector-wire.ts";
|
|
23
|
+
export * from "./pick.ts";
|
|
24
|
+
// The Chart (ADR-0070): its grammar (`chartSchema`, which a Chart wrapper's door and a planner's pick
|
|
25
|
+
// import), the door that admits one, and the resolver of its references.
|
|
26
|
+
export * from "./chart.ts";
|
|
27
|
+
// The Open body a Chart binds (`openBody`, the slot constructor a Chart wrapper places in `actors`)
|
|
28
|
+
// and the named Charts of an Instance: Chart files and runtime Charts (ADR-0070).
|
|
29
|
+
export * from "./open-body.ts";
|
|
30
|
+
export * from "./charts.ts";
|
|
12
31
|
export * from "./parts.ts";
|
|
32
|
+
export * from "./size.ts";
|
|
13
33
|
export * from "./customize.ts";
|
|
14
34
|
export * from "./ambient.ts";
|
|
15
35
|
export * from "./config.ts";
|
|
16
36
|
export * from "./repo-identity.ts";
|
|
17
37
|
export * from "./pool.ts";
|
|
18
38
|
export * from "./setup.ts";
|
|
39
|
+
// The author's routing guard (ADR-0015).
|
|
40
|
+
export { sentBy } from "./party.ts";
|
|
19
41
|
export * from "./vocabulary.ts";
|
|
20
42
|
export * from "./tokens.ts";
|
|
21
43
|
export * from "./durability.ts";
|
|
@@ -24,12 +46,35 @@ export * from "./actor.ts";
|
|
|
24
46
|
export * from "./gate.ts";
|
|
25
47
|
export * from "./workspace.ts";
|
|
26
48
|
export * from "./images.ts";
|
|
27
|
-
|
|
49
|
+
// The Assembly's content address and wire form (ADR-0069): `jr2 up` and the door share both.
|
|
50
|
+
export * from "./content-hash.ts";
|
|
51
|
+
export * from "./assembly-tar.ts";
|
|
52
|
+
// The current Assembly and the publish door (ADR-0069), and the walk's refusal listing that
|
|
53
|
+
// `jr2 up` and the door both run.
|
|
54
|
+
export * from "./assembly.ts";
|
|
55
|
+
export * from "./assembly-checks.ts";
|
|
56
|
+
export * from "./mount-digest.ts";
|
|
57
|
+
export * from "./model-keys.ts";
|
|
58
|
+
export * from "./held-secrets.ts";
|
|
59
|
+
export * from "./secret-placement.ts";
|
|
60
|
+
export * from "./git-push.ts";
|
|
61
|
+
export * from "./git-clone.ts";
|
|
62
|
+
export * from "./custodian.ts";
|
|
63
|
+
export * from "./sandbox-kube.ts";
|
|
64
|
+
export {
|
|
65
|
+
effectorManifestKey,
|
|
66
|
+
LABEL_EFFECTOR_POD,
|
|
67
|
+
readSandboxEffectorManifest,
|
|
68
|
+
sandboxEffectorKeySecret,
|
|
69
|
+
sandboxEffectorObjectsOf,
|
|
70
|
+
type ProjectedSecret,
|
|
71
|
+
type SandboxEffectorManifest,
|
|
72
|
+
} from "./sandbox-effector.ts";
|
|
28
73
|
export * from "./repos.ts";
|
|
29
74
|
export * from "./repo-fetch.ts";
|
|
30
75
|
// Type-only: what a workflow event delivery looks like (the registration TABLE stays internal —
|
|
31
76
|
// ADR-0011: workflows speak only defineEvent/agent/gate).
|
|
32
|
-
export type { DeliveredEvent } from "./registration.ts";
|
|
77
|
+
export type { ChildErrorMarker, DeliveredEvent, PlacingMarker, RunMarker, TurnMarker } from "./registration.ts";
|
|
33
78
|
export * from "./machine-doc.ts";
|
|
34
79
|
export * from "./run-host.ts";
|
|
35
80
|
export * from "./http.ts";
|