@inhuman.tools/plexus-expectations 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +144 -2
  3. package/dist/driver/ExpectationActor.d.ts +56 -0
  4. package/dist/driver/ExpectationActor.d.ts.map +1 -0
  5. package/dist/driver/ExpectationActor.js +210 -0
  6. package/dist/driver/ExpectationActor.js.map +1 -0
  7. package/dist/driver/PEWDriver.d.ts +144 -0
  8. package/dist/driver/PEWDriver.d.ts.map +1 -0
  9. package/dist/driver/PEWDriver.js +303 -0
  10. package/dist/driver/PEWDriver.js.map +1 -0
  11. package/dist/driver/actor-machine.d.ts +28 -0
  12. package/dist/driver/actor-machine.d.ts.map +1 -0
  13. package/dist/driver/actor-machine.js +50 -0
  14. package/dist/driver/actor-machine.js.map +1 -0
  15. package/dist/driver/connection-miss.d.ts +9 -0
  16. package/dist/driver/connection-miss.d.ts.map +1 -0
  17. package/dist/driver/connection-miss.js +13 -0
  18. package/dist/driver/connection-miss.js.map +1 -0
  19. package/dist/driver/index.d.ts +6 -0
  20. package/dist/driver/index.d.ts.map +1 -0
  21. package/dist/driver/index.js +5 -0
  22. package/dist/driver/index.js.map +1 -0
  23. package/dist/executor/index.d.ts +4 -0
  24. package/dist/executor/index.d.ts.map +1 -0
  25. package/dist/executor/index.js +4 -0
  26. package/dist/executor/index.js.map +1 -0
  27. package/dist/executor/kernel-intern.d.ts +16 -0
  28. package/dist/executor/kernel-intern.d.ts.map +1 -0
  29. package/dist/executor/kernel-intern.js +98 -0
  30. package/dist/executor/kernel-intern.js.map +1 -0
  31. package/dist/executor/orchestrator.d.ts +97 -0
  32. package/dist/executor/orchestrator.d.ts.map +1 -0
  33. package/dist/executor/orchestrator.js +465 -0
  34. package/dist/executor/orchestrator.js.map +1 -0
  35. package/dist/executor/types.d.ts +8 -0
  36. package/dist/executor/types.d.ts.map +1 -0
  37. package/dist/executor/types.js +2 -0
  38. package/dist/executor/types.js.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +2 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/schemas/connection.d.ts +4 -0
  44. package/dist/schemas/connection.d.ts.map +1 -0
  45. package/dist/schemas/connection.js +4 -0
  46. package/dist/schemas/connection.js.map +1 -0
  47. package/dist/schemas/index.d.ts +2 -0
  48. package/dist/schemas/index.d.ts.map +1 -0
  49. package/dist/schemas/index.js +2 -0
  50. package/dist/schemas/index.js.map +1 -0
  51. package/dist/shared/control.d.ts +4 -0
  52. package/dist/shared/control.d.ts.map +1 -0
  53. package/dist/shared/control.js +2 -0
  54. package/dist/shared/control.js.map +1 -0
  55. package/dist/shared/index.d.ts +7 -0
  56. package/dist/shared/index.d.ts.map +1 -0
  57. package/dist/shared/index.js +7 -0
  58. package/dist/shared/index.js.map +1 -0
  59. package/dist/shared/map-field-awareness.d.ts +19 -0
  60. package/dist/shared/map-field-awareness.d.ts.map +1 -0
  61. package/dist/shared/map-field-awareness.js +58 -0
  62. package/dist/shared/map-field-awareness.js.map +1 -0
  63. package/dist/shared/models/ConnectionSpec.d.ts +44 -0
  64. package/dist/shared/models/ConnectionSpec.d.ts.map +1 -0
  65. package/dist/shared/models/ConnectionSpec.js +180 -0
  66. package/dist/shared/models/ConnectionSpec.js.map +1 -0
  67. package/dist/shared/models/DriverSpec.d.ts +45 -0
  68. package/dist/shared/models/DriverSpec.d.ts.map +1 -0
  69. package/dist/shared/models/DriverSpec.js +221 -0
  70. package/dist/shared/models/DriverSpec.js.map +1 -0
  71. package/dist/shared/models/Job.d.ts +85 -0
  72. package/dist/shared/models/Job.d.ts.map +1 -0
  73. package/dist/shared/models/Job.js +261 -0
  74. package/dist/shared/models/Job.js.map +1 -0
  75. package/dist/shared/models/WorkContainer.d.ts +36 -0
  76. package/dist/shared/models/WorkContainer.d.ts.map +1 -0
  77. package/dist/shared/models/WorkContainer.js +140 -0
  78. package/dist/shared/models/WorkContainer.js.map +1 -0
  79. package/dist/shared/models/WorkExpectation.d.ts +63 -0
  80. package/dist/shared/models/WorkExpectation.d.ts.map +1 -0
  81. package/dist/shared/models/WorkExpectation.js +290 -0
  82. package/dist/shared/models/WorkExpectation.js.map +1 -0
  83. package/dist/shared/models/index.d.ts +7 -0
  84. package/dist/shared/models/index.d.ts.map +1 -0
  85. package/dist/shared/models/index.js +6 -0
  86. package/dist/shared/models/index.js.map +1 -0
  87. package/dist/shared/models/jsonRecord.d.ts +14 -0
  88. package/dist/shared/models/jsonRecord.d.ts.map +1 -0
  89. package/dist/shared/models/jsonRecord.js +46 -0
  90. package/dist/shared/models/jsonRecord.js.map +1 -0
  91. package/dist/shared/revalidation-demand.d.ts +27 -0
  92. package/dist/shared/revalidation-demand.d.ts.map +1 -0
  93. package/dist/shared/revalidation-demand.js +116 -0
  94. package/dist/shared/revalidation-demand.js.map +1 -0
  95. package/dist/shared/role.d.ts +12 -0
  96. package/dist/shared/role.d.ts.map +1 -0
  97. package/dist/shared/role.js +21 -0
  98. package/dist/shared/role.js.map +1 -0
  99. package/dist/shared/types.d.ts +43 -0
  100. package/dist/shared/types.d.ts.map +1 -0
  101. package/dist/shared/types.js +12 -0
  102. package/dist/shared/types.js.map +1 -0
  103. package/package.json +79 -3
  104. package/src/driver/ExpectationActor.ts +244 -0
  105. package/src/driver/PEWDriver.ts +302 -0
  106. package/src/driver/actor-machine.ts +54 -0
  107. package/src/driver/connection-miss.ts +13 -0
  108. package/src/driver/index.ts +5 -0
  109. package/src/executor/index.ts +3 -0
  110. package/src/executor/kernel-intern.ts +121 -0
  111. package/src/executor/orchestrator.ts +463 -0
  112. package/src/executor/types.ts +3 -0
  113. package/src/index.ts +1 -0
  114. package/src/schemas/connection.ts +4 -0
  115. package/src/schemas/index.ts +1 -0
  116. package/src/shared/control.ts +4 -0
  117. package/src/shared/index.ts +6 -0
  118. package/src/shared/map-field-awareness.ts +65 -0
  119. package/src/shared/models/ConnectionSpec.ts +84 -0
  120. package/src/shared/models/DriverSpec.ts +102 -0
  121. package/src/shared/models/Job.ts +192 -0
  122. package/src/shared/models/WorkContainer.ts +90 -0
  123. package/src/shared/models/WorkExpectation.ts +229 -0
  124. package/src/shared/models/index.ts +6 -0
  125. package/src/shared/models/jsonRecord.ts +49 -0
  126. package/src/shared/revalidation-demand.ts +121 -0
  127. package/src/shared/role.ts +32 -0
  128. package/src/shared/types.ts +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-intern.js","sourceRoot":"","sources":["../../src/executor/kernel-intern.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Process-local connection intern table keyed by the kernel root object.\n *\n * Session wrap is Yjs load. Park drops an owner ref and must not dispose the\n * instance — {@link disposeKernelConnections} is kernel teardown only.\n * Rejected: last-ref dispose. Switching seats reminted every driver.\n */\nimport { DefaultedWeakMap } from \"@here.build/collections\";\nimport { comparer, reaction, type IReactionDisposer } from \"mobx\";\n\nimport { ConnectionMiss } from \"../driver/connection-miss.js\";\nimport { extraLiveFromState, type PEWDriver } from \"../driver/PEWDriver.js\";\nimport type { ConnectionSpec } from \"../shared/models/ConnectionSpec.js\";\nimport { asReadyState } from \"../shared/types.js\";\n\ntype InternOwner = { forgetConnection(id: string): void };\n\nfunction internOwnerOf(owner: object): InternOwner | undefined {\n return typeof (owner as InternOwner).forgetConnection === \"function\" ? (owner as InternOwner) : undefined;\n}\n\ntype KernelRoot = { readonly connections: Record<string, ConnectionSpec | undefined> };\ntype ConnectionHold = {\n readonly refs: Set<object>;\n readonly pending: Promise<PEWDriver>;\n mirror: IReactionDisposer | undefined;\n};\ntype KernelIntern = { readonly connections: Map<string, ConnectionHold> };\n\nconst internByKernel = new DefaultedWeakMap<object, KernelIntern>(() => ({ connections: new Map() }));\n\nexport function acquireConnection(\n kernel: KernelRoot,\n owner: object,\n connectionId: string,\n construct: () => PEWDriver | Promise<PEWDriver>,\n): Promise<PEWDriver> {\n const bag = internByKernel.get(kernel);\n const existing = bag.connections.get(connectionId);\n if (existing !== undefined) {\n existing.refs.add(owner);\n return existing.pending;\n }\n const lease: ConnectionHold = {\n refs: new Set([owner]),\n pending: Promise.resolve().then(construct).then((instance) => {\n lease.mirror = reaction(\n () => {\n const spec = kernel.connections[connectionId];\n if (spec === undefined) return null;\n const ready = asReadyState(instance.readyState);\n // Bootstrapping remint must not wipe a ready catalog.\n if (ready !== \"ready\" && ready !== \"failed\" && spec.readyState === \"ready\") return null;\n return { ready, error: instance.error, live: extraLiveFromState(instance.state) };\n },\n (snap) => {\n if (snap == null) return;\n kernel.connections[connectionId]?.stampProcess({\n readyState: snap.ready,\n error: snap.error,\n live: snap.live,\n });\n },\n { fireImmediately: true, equals: comparer.structural },\n );\n return instance;\n }),\n mirror: undefined,\n };\n bag.connections.set(connectionId, lease);\n void lease.pending.then(undefined, () => {\n if (lease.refs.size === 0) bag.connections.delete(connectionId);\n });\n return lease.pending;\n}\n\nexport function releaseConnection(kernel: object, owner: object, connectionId: string): void {\n if (!internByKernel.has(kernel)) return;\n internByKernel.get(kernel).connections.get(connectionId)?.refs.delete(owner);\n}\n\n/**\n * Remint door. Logout/drop — not park, not last-ref.\n * Pending lease still `asyncDispose`s when it fulfills. Next `ensure` remints.\n */\nexport async function dropConnection(kernel: KernelRoot, connectionId: string): Promise<void> {\n if (!internByKernel.has(kernel)) return;\n const bag = internByKernel.get(kernel);\n const lease = bag.connections.get(connectionId);\n if (lease === undefined) return;\n bag.connections.delete(connectionId);\n lease.mirror?.();\n const owners = [...lease.refs];\n lease.refs.clear();\n const miss = new ConnectionMiss(\"connection-dropped\", `connection ${connectionId} dropped`);\n const disposing = lease.pending.then(\n (instance) => {\n instance.abortOnDrop(miss);\n return instance[Symbol.asyncDispose]();\n },\n () => {},\n );\n for (const owner of owners) internOwnerOf(owner)?.forgetConnection(connectionId);\n await disposing;\n}\n\n/** Kernel teardown only. Session park is a document wrap, not a connection lifetime. */\nexport function disposeKernelConnections(kernel: object): void {\n if (!internByKernel.has(kernel)) return;\n const bag = internByKernel.get(kernel);\n internByKernel.delete(kernel);\n for (const lease of bag.connections.values()) {\n lease.refs.clear();\n lease.mirror?.();\n void lease.pending.then(\n (instance) => instance[Symbol.asyncDispose](),\n () => {},\n );\n }\n bag.connections.clear();\n}\n"]}
@@ -0,0 +1,97 @@
1
+ import { ExpectationActor } from "../driver/ExpectationActor.js";
2
+ import { type ConnectionSecretsView, type DriverConnectionClass, type PEWDriver } from "../driver/PEWDriver.js";
3
+ import { DriverSpec } from "../shared/models/DriverSpec.js";
4
+ import { Job } from "../shared/models/Job.js";
5
+ import { type AnyWorkExpectation, WorkExpectation } from "../shared/models/WorkExpectation.js";
6
+ import { type KernelPlexus, type SessionPlexus } from "../shared/types.js";
7
+ /** Class identity for `instanceof`. `registerExecutor` never constructs. */
8
+ export type JobConstructor<T extends Job = Job> = abstract new (...args: any[]) => T;
9
+ /**
10
+ * Seam: session work graph → honor (PEW) and claim (Job).
11
+ *
12
+ * Honor is reachable PEW → handle. Unstarted cancel writes the durable
13
+ * ending here and must not poke `ensure` — MCP: an unstarted tool must not
14
+ * spin the server. Do not call `Actor.complete` — unstarted Work has no
15
+ * Actor. `handle` is not the sealer. License is phase 1 on an Approvable
16
+ * leaf. A sealed parent is not honored (the
17
+ * child is already ending in the agentic runtime, or must not start).
18
+ *
19
+ * INTERN TABLE IS NOT AN ATOM. `#connections` is a plain Map of kernel-interned
20
+ * instances (one live driver per kernel connection id). Honor re-enters by
21
+ * reading catalog `spec.readyState` and, once minted, `instance.readyState`.
22
+ * `handle` only when `ready`.
23
+ *
24
+ * A rejected ensure/load memo IS the sticky failure (no hot loop).
25
+ *
26
+ * Honor and Job claim do not start in the constructor. PEW autorun used to
27
+ * run during `super()`, so a readiness Promise after construct was not a
28
+ * gate. Call {@link activate} after replicas are pinned and recovery ran.
29
+ *
30
+ * Import discipline: this module does not import harness or the session document.
31
+ */
32
+ export declare abstract class Orchestrator<K extends KernelPlexus = KernelPlexus, S extends SessionPlexus = SessionPlexus> implements Disposable {
33
+ #private;
34
+ readonly kernel: K;
35
+ readonly session: S;
36
+ /**
37
+ * Origin-dispatched PEW skip. Lives here, not on the session subclass:
38
+ * honor used to run during `super()`, and subclass fields are unassigned
39
+ * then (JS). A child WeakSet made `shouldHonor` throw `undefined.has`.
40
+ */
41
+ protected readonly originCompletions: WeakSet<WorkExpectation<unknown, unknown>>;
42
+ constructor(kernel: K, session: S);
43
+ protected get reachableJobs(): Job[];
44
+ /**
45
+ * Two functions. License (phase 1) returns `true` | `false` and writes
46
+ * `orchestrationResult` (`orchestrated` follows). `true` → await execute
47
+ * (phase 2). `false` → skip execute, `completed = true`. Bootstrap
48
+ * `orchestrated && !completed` skips the license and runs execute.
49
+ * `signal` aborts when the job leaves the graph or the orchestrator disposes.
50
+ */
51
+ registerExecutor<T extends Job>(Class: JobConstructor<T>, license: (job: T, orchestrator: this) => boolean | Promise<boolean>, execute: (job: T, signal: AbortSignal, orchestrator: this) => void | Promise<void>, options?: {
52
+ readonly seal?: boolean;
53
+ }): void;
54
+ /**
55
+ * Host hook: a guard or body threw. `job.crash` is set; write the receipt
56
+ * the job's joiners read (a tool outcome, a call failure). The orchestrator
57
+ * completes the job right after.
58
+ */
59
+ protected stampCrash(_job: Job, _phase: "license" | "body", _detail: string): void;
60
+ /** In-flight claimed Jobs (handler has not `finally`'d). */
61
+ protected inFlightJobs(): Iterable<Job>;
62
+ /** Abort an in-flight executor. No-op if the job is not claimed here. */
63
+ abortJob(job: Job, reason?: unknown): void;
64
+ abstract loadDriverModule(driver: DriverSpec): Promise<DriverConnectionClass>;
65
+ /**
66
+ * Honor still `handle`s leftover attach PEW. Origin-dispatched completions
67
+ * return false (PR4). Default true unless the node is in {@link originCompletions}.
68
+ */
69
+ protected shouldHonor(node: WorkExpectation): boolean;
70
+ /** Process-local. Secrets are never a Plexus field. */
71
+ protected connectionSecrets(_connectionId: string): ConnectionSecretsView;
72
+ /** After bootstrap, before ensure settles. The session host binds the settings writer here. */
73
+ protected attachConnection(_connectionId: string, _instance: PEWDriver): void;
74
+ connectionOf(expectation: WorkExpectation): PEWDriver | undefined;
75
+ actorOf<T extends AnyWorkExpectation>(expectation: T): ExpectationActor<T> | undefined;
76
+ ensure(connectionId: string): Promise<PEWDriver>;
77
+ /** True once the connection memo has been poked — without poking it. */
78
+ protected isEnsured(connectionId: string): boolean;
79
+ /** Intern-owner remint. Deletes the sticky `#ensured` memo. */
80
+ forgetConnection(id: string): void;
81
+ /** True after {@link activate}; constructor and registerExecutor do not honor. */
82
+ get activated(): boolean;
83
+ /**
84
+ * Start honor, Job claim, and driver discovery. Idempotent. No-op after
85
+ * park/dispose — those already stopped admission.
86
+ */
87
+ activate(): void;
88
+ /**
89
+ * Stop honor and new claim. In-flight BODY and live connections stay —
90
+ * park waits dispatched MCP before {@link Symbol.dispose} releases them.
91
+ */
92
+ protected stopAdmission(): void;
93
+ [Symbol.dispose](): void;
94
+ get drivers(): Record<string, DriverSpec>;
95
+ get connections(): Record<string, import("../index.js").ConnectionSpec>;
96
+ }
97
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/executor/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,465 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
35
+ import { DefaultedMap } from "@here.build/collections";
36
+ import { action, autorun, comparer, computed, observable, reaction, toJS } from "mobx";
37
+ import invariant from "tiny-invariant";
38
+ import { acquireConnection, releaseConnection, } from "./kernel-intern.js";
39
+ import { extraLiveFromState, isDriverConnectionClass, } from "../driver/PEWDriver.js";
40
+ import { Job } from "../shared/models/Job.js";
41
+ import { WorkContainer, walkWork } from "../shared/models/WorkContainer.js";
42
+ import { WorkExpectation, isTreeOrphan } from "../shared/models/WorkExpectation.js";
43
+ /**
44
+ * Seam: session work graph → honor (PEW) and claim (Job).
45
+ *
46
+ * Honor is reachable PEW → handle. Unstarted cancel writes the durable
47
+ * ending here and must not poke `ensure` — MCP: an unstarted tool must not
48
+ * spin the server. Do not call `Actor.complete` — unstarted Work has no
49
+ * Actor. `handle` is not the sealer. License is phase 1 on an Approvable
50
+ * leaf. A sealed parent is not honored (the
51
+ * child is already ending in the agentic runtime, or must not start).
52
+ *
53
+ * INTERN TABLE IS NOT AN ATOM. `#connections` is a plain Map of kernel-interned
54
+ * instances (one live driver per kernel connection id). Honor re-enters by
55
+ * reading catalog `spec.readyState` and, once minted, `instance.readyState`.
56
+ * `handle` only when `ready`.
57
+ *
58
+ * A rejected ensure/load memo IS the sticky failure (no hot loop).
59
+ *
60
+ * Honor and Job claim do not start in the constructor. PEW autorun used to
61
+ * run during `super()`, so a readiness Promise after construct was not a
62
+ * gate. Call {@link activate} after replicas are pinned and recovery ran.
63
+ *
64
+ * Import discipline: this module does not import harness or the session document.
65
+ */
66
+ let Orchestrator = (() => {
67
+ let _instanceExtraInitializers = [];
68
+ let _get_reachableJobs_decorators;
69
+ return class Orchestrator {
70
+ static {
71
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
72
+ __esDecorate(this, null, _get_reachableJobs_decorators, { kind: "getter", name: "reachableJobs", static: false, private: false, access: { has: obj => "reachableJobs" in obj, get: obj => obj.reachableJobs }, metadata: _metadata }, null, _instanceExtraInitializers);
73
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
74
+ }
75
+ kernel = __runInitializers(this, _instanceExtraInitializers);
76
+ session;
77
+ #disposed = false;
78
+ #admissionStopped = false;
79
+ #activated = observable.box(false);
80
+ #disposeWork;
81
+ /** Disposed with the orchestrator — a dead session must not keep writing the live kernel catalog. */
82
+ #mirrorDisposers = [];
83
+ #processes = new Map();
84
+ /** Execute (phase 2) — started BODY. */
85
+ #jobAbort = new Map();
86
+ /** In-flight license (phase 1). */
87
+ #guardAbort = new Map();
88
+ /**
89
+ * Process-local: execute already claimed this job. Survives seal:false
90
+ * so the starter does not re-run BODY. A new Orchestrator is empty —
91
+ * bootstrap `orchestrated && !completed` runs execute once more.
92
+ */
93
+ #bodyStarted = new WeakSet();
94
+ /**
95
+ * Origin-dispatched PEW skip. Lives here, not on the session subclass:
96
+ * honor used to run during `super()`, and subclass fields are unassigned
97
+ * then (JS). A child WeakSet made `shouldHonor` throw `undefined.has`.
98
+ */
99
+ originCompletions = new WeakSet();
100
+ #disposeAborts;
101
+ constructor(kernel, session) {
102
+ this.kernel = kernel;
103
+ this.session = session;
104
+ this.#mirrorDisposers.push(autorun(() => {
105
+ if (this.#disposed || !this.#activated.get())
106
+ return;
107
+ for (const name of Object.keys(this.drivers)) {
108
+ // Driver discovery is intentionally eager so the kernel catalog can
109
+ // expose class-side offers and live facts before a connection is
110
+ // ensured. A session may not be able to load every driver in a
111
+ // shared kernel, so consume a rejected discovery promise here; the
112
+ // driver spec already carries the failure for interested readers.
113
+ void this.#classes.get(name).catch(() => { });
114
+ }
115
+ }));
116
+ this.#disposeWork = autorun(() => {
117
+ if (this.#disposed || !this.#activated.get())
118
+ return;
119
+ for (const node of collectReachable(this.session.root)) {
120
+ if (node.isDone || isTreeOrphan(node))
121
+ continue;
122
+ if (!this.shouldHonor(node))
123
+ continue;
124
+ const spec = this.connections[node.connectionId];
125
+ if (spec === undefined)
126
+ continue;
127
+ void spec.readyState;
128
+ const instance = this.#connections.get(node.connectionId);
129
+ if (instance !== undefined) {
130
+ if (instance.readyState === "ready")
131
+ instance.handle(node);
132
+ continue;
133
+ }
134
+ invariant(Object.hasOwn(this.connections, node.connectionId), `unknown connection ${node.connectionId}`);
135
+ void this.ensure(node.connectionId);
136
+ }
137
+ });
138
+ this.#disposeAborts = autorun(() => {
139
+ if (this.#disposed || !this.#activated.get())
140
+ return;
141
+ const live = new Set(this.reachableJobs);
142
+ for (const [job, ac] of this.#jobAbort) {
143
+ if (live.has(job) || ac.signal.aborted)
144
+ continue;
145
+ ac.abort();
146
+ }
147
+ for (const [job, ac] of this.#guardAbort) {
148
+ if (live.has(job) || ac.signal.aborted)
149
+ continue;
150
+ ac.abort();
151
+ }
152
+ });
153
+ }
154
+ get reachableJobs() {
155
+ const root = this.session.root;
156
+ const jobs = new Set();
157
+ if (root instanceof Job)
158
+ jobs.add(root);
159
+ if (root instanceof WorkContainer) {
160
+ for (const job of Iterator.from(walkWork(root)).filter((node) => node instanceof Job)) {
161
+ jobs.add(job);
162
+ }
163
+ }
164
+ return [...jobs];
165
+ }
166
+ /**
167
+ * Two functions. License (phase 1) returns `true` | `false` and writes
168
+ * `orchestrationResult` (`orchestrated` follows). `true` → await execute
169
+ * (phase 2). `false` → skip execute, `completed = true`. Bootstrap
170
+ * `orchestrated && !completed` skips the license and runs execute.
171
+ * `signal` aborts when the job leaves the graph or the orchestrator disposes.
172
+ */
173
+ registerExecutor(Class, license, execute, options) {
174
+ invariant(!this.#processes.has(Class), `Orchestrator: executor already registered for ${Class.name}`);
175
+ const seal = options?.seal !== false;
176
+ this.#processes.set(Class, autorun(() => {
177
+ if (this.#disposed || !this.#activated.get())
178
+ return;
179
+ for (const node of this.reachableJobs) {
180
+ if (!(node instanceof Class))
181
+ continue;
182
+ const job = node;
183
+ if (job.completed || job.cancelled)
184
+ continue;
185
+ if (job.orchestrationResult === false) {
186
+ job.markComplete();
187
+ continue;
188
+ }
189
+ if (job.orchestrationResult === true) {
190
+ this.#startExecute(job, execute, seal);
191
+ continue;
192
+ }
193
+ if (this.#guardAbort.has(job) || this.#jobAbort.has(job))
194
+ continue;
195
+ // Ordering is data on the job: wait here until every predecessor is released.
196
+ if (!job.afterReleased)
197
+ continue;
198
+ this.#startGuard(job, license, execute, seal);
199
+ }
200
+ }));
201
+ }
202
+ #startGuard(job, license, execute, seal) {
203
+ const settle = action((ok) => {
204
+ if (job.orchestrationResult !== null || job.completed || job.cancelled)
205
+ return;
206
+ job.orchestrationResult = ok;
207
+ if (ok) {
208
+ this.#startExecute(job, execute, seal);
209
+ }
210
+ else {
211
+ job.markComplete();
212
+ }
213
+ });
214
+ // A guard that threw never licensed the job: deny it with a crash receipt.
215
+ const crashed = action((error) => {
216
+ if (job.orchestrationResult !== null || job.completed || job.cancelled)
217
+ return;
218
+ this.#recordCrash(job, "license", error);
219
+ job.orchestrationResult = false;
220
+ job.markComplete();
221
+ });
222
+ try {
223
+ const result = license(job, this);
224
+ if (typeof result === "boolean") {
225
+ settle(result);
226
+ return;
227
+ }
228
+ const ac = new AbortController();
229
+ this.#guardAbort.set(job, ac);
230
+ void result.then((ok) => {
231
+ if (ac.signal.aborted)
232
+ return;
233
+ settle(ok);
234
+ return ok;
235
+ }, (error) => {
236
+ if (ac.signal.aborted)
237
+ return;
238
+ crashed(error);
239
+ }).finally(action(() => {
240
+ this.#guardAbort.delete(job);
241
+ }));
242
+ }
243
+ catch (error) {
244
+ crashed(error);
245
+ }
246
+ }
247
+ #startExecute(job, execute, seal) {
248
+ if (this.#bodyStarted.has(job) || job.completed || job.cancelled)
249
+ return;
250
+ if (job.orchestrationResult !== true)
251
+ return;
252
+ this.#bodyStarted.add(job);
253
+ action(() => {
254
+ job.markStarted();
255
+ })();
256
+ const ac = new AbortController();
257
+ this.#jobAbort.set(job, ac);
258
+ void Promise.resolve()
259
+ .then(() => execute(job, ac.signal, this))
260
+ .then(() => false, (error) => {
261
+ // An abort (cancel, park, leaving the graph) is not a crash: the aborter owns the ending.
262
+ if (ac.signal.aborted || job.completed || job.cancelled)
263
+ return false;
264
+ action(() => this.#recordCrash(job, "body", error))();
265
+ return true;
266
+ })
267
+ .then(action((crashed) => {
268
+ if (seal || crashed)
269
+ job.markComplete();
270
+ this.#jobAbort.delete(job);
271
+ }))
272
+ .catch(() => { });
273
+ }
274
+ #recordCrash(job, phase, error) {
275
+ const detail = error instanceof Error ? error.message : String(error);
276
+ job.crash = `${phase}: ${detail === "" ? "unknown error" : detail}`;
277
+ try {
278
+ this.stampCrash(job, phase, detail);
279
+ }
280
+ catch {
281
+ /* the crash fact is already on the job; the receipt is best effort */
282
+ }
283
+ }
284
+ /**
285
+ * Host hook: a guard or body threw. `job.crash` is set; write the receipt
286
+ * the job's joiners read (a tool outcome, a call failure). The orchestrator
287
+ * completes the job right after.
288
+ */
289
+ stampCrash(_job, _phase, _detail) { }
290
+ /** In-flight claimed Jobs (handler has not `finally`'d). */
291
+ inFlightJobs() {
292
+ return this.#jobAbort.keys();
293
+ }
294
+ /** Abort an in-flight executor. No-op if the job is not claimed here. */
295
+ abortJob(job, reason) {
296
+ this.#jobAbort.get(job)?.abort(reason);
297
+ }
298
+ #connections = new Map();
299
+ #classes = new DefaultedMap(this.#loadDriverClass.bind(this));
300
+ #ensured = new DefaultedMap(this.#ensureConnection.bind(this));
301
+ /**
302
+ * Honor still `handle`s leftover attach PEW. Origin-dispatched completions
303
+ * return false (PR4). Default true unless the node is in {@link originCompletions}.
304
+ */
305
+ shouldHonor(node) {
306
+ return !this.originCompletions.has(node);
307
+ }
308
+ /** Process-local. Secrets are never a Plexus field. */
309
+ connectionSecrets(_connectionId) {
310
+ return { get: () => undefined };
311
+ }
312
+ /** After bootstrap, before ensure settles. The session host binds the settings writer here. */
313
+ attachConnection(_connectionId, _instance) { }
314
+ connectionOf(expectation) {
315
+ return this.#connections.get(expectation.connectionId);
316
+ }
317
+ actorOf(expectation) {
318
+ const connection = this.connectionOf(expectation);
319
+ if (!connection?.has(expectation))
320
+ return undefined;
321
+ return connection.resolveExpectation(expectation);
322
+ }
323
+ #loadDriverClass(driverName) {
324
+ return (async () => {
325
+ // JS: subclass fields (SessionOrchestrator.sessionDaemon) are unassigned during super().
326
+ await Promise.resolve();
327
+ const driver = this.drivers[driverName];
328
+ invariant(driver !== undefined, `unknown driver ${driverName}`);
329
+ try {
330
+ const cls = await this.loadDriverModule(driver);
331
+ invariant(isDriverConnectionClass(cls), "loadDriverModule: result is not a PEWDriver class");
332
+ // Occupancy is kernel-plane: interned connections outlive a session wrap.
333
+ cls.awareness = this.kernel.awareness;
334
+ cls.driverName = driverName;
335
+ const spec = this.drivers[driverName];
336
+ if (spec !== undefined) {
337
+ spec.stampLoad({
338
+ readyState: "ready",
339
+ error: "",
340
+ offersJson: JSON.stringify(cls.offers),
341
+ live: extraLiveFromState(cls.state),
342
+ });
343
+ // Offers are class state a driver may keep fresh (local detection). The
344
+ // reaction also holds the observation that wakes a lazy `cls.offers`.
345
+ this.#mirrorDisposers.push(reaction(() => toJS(cls.offers), (offers) => {
346
+ if (!this.#disposed)
347
+ spec.offers = offers;
348
+ }, { equals: comparer.structural }));
349
+ }
350
+ return cls;
351
+ }
352
+ catch (error) {
353
+ const spec = this.drivers[driverName];
354
+ if (spec !== undefined)
355
+ spec.stampLoad({ readyState: "failed", error: String(error) });
356
+ throw error;
357
+ }
358
+ })();
359
+ }
360
+ #ensureConnection(connectionId) {
361
+ const pending = (async () => {
362
+ const driver = this.kernel.root.connections[connectionId]?.driver;
363
+ invariant(driver !== undefined, `unknown driver for connection ${connectionId}`);
364
+ const instance = await acquireConnection(this.kernel.root, this, connectionId, async () => {
365
+ const cls = await this.#classes.get(driver.name);
366
+ const minted = new cls(connectionId,
367
+ // YAML: settings stamped onto the connection before ensure.
368
+ this.kernel.root.connections[connectionId]?.configuration ?? {}, this.connectionSecrets(connectionId));
369
+ action(() => {
370
+ minted.awareness = this.kernel.awareness; // kernel occupancy, not session
371
+ })();
372
+ return minted;
373
+ });
374
+ action(() => {
375
+ instance.awareness = this.kernel.awareness;
376
+ })();
377
+ this.#connections.set(connectionId, instance);
378
+ await instance.ensureBootstrapStarted();
379
+ this.attachConnection(connectionId, instance);
380
+ return instance;
381
+ })();
382
+ void pending.then(undefined, () => { });
383
+ return pending;
384
+ }
385
+ ensure(connectionId) {
386
+ return this.#ensured.get(connectionId);
387
+ }
388
+ /** True once the connection memo has been poked — without poking it. */
389
+ isEnsured(connectionId) {
390
+ return this.#ensured.has(connectionId);
391
+ }
392
+ /** Intern-owner remint. Deletes the sticky `#ensured` memo. */
393
+ forgetConnection(id) {
394
+ this.#ensured.delete(id);
395
+ this.#connections.delete(id);
396
+ releaseConnection(this.kernel.root, this, id);
397
+ }
398
+ /** True after {@link activate}; constructor and registerExecutor do not honor. */
399
+ get activated() {
400
+ return this.#activated.get();
401
+ }
402
+ /**
403
+ * Start honor, Job claim, and driver discovery. Idempotent. No-op after
404
+ * park/dispose — those already stopped admission.
405
+ */
406
+ activate() {
407
+ if (this.#disposed || this.#admissionStopped)
408
+ return;
409
+ action(() => {
410
+ this.#activated.set(true);
411
+ })();
412
+ }
413
+ /**
414
+ * Stop honor and new claim. In-flight BODY and live connections stay —
415
+ * park waits dispatched MCP before {@link Symbol.dispose} releases them.
416
+ */
417
+ stopAdmission() {
418
+ if (this.#admissionStopped)
419
+ return;
420
+ this.#admissionStopped = true;
421
+ this.#disposeWork();
422
+ for (const dispose of this.#processes.values())
423
+ dispose();
424
+ this.#processes.clear();
425
+ for (const ac of this.#guardAbort.values())
426
+ ac.abort("park");
427
+ }
428
+ [(_get_reachableJobs_decorators = [computed], Symbol.dispose)]() {
429
+ if (this.#disposed)
430
+ return;
431
+ this.#disposed = true;
432
+ this.stopAdmission();
433
+ for (const ac of this.#jobAbort.values())
434
+ ac.abort();
435
+ for (const ac of this.#guardAbort.values())
436
+ ac.abort();
437
+ this.#disposeAborts();
438
+ this.#jobAbort.clear();
439
+ this.#guardAbort.clear();
440
+ for (const id of this.#connections.keys())
441
+ releaseConnection(this.kernel.root, this, id);
442
+ this.#connections.clear();
443
+ for (const dispose of this.#mirrorDisposers.splice(0))
444
+ dispose();
445
+ }
446
+ get drivers() {
447
+ return this.kernel.root.drivers;
448
+ }
449
+ get connections() {
450
+ return this.kernel.root.connections;
451
+ }
452
+ };
453
+ })();
454
+ export { Orchestrator };
455
+ function collectReachable(root) {
456
+ if (!(root instanceof WorkContainer))
457
+ return new Set();
458
+ const found = new Set();
459
+ for (const node of walkWork(root)) {
460
+ if (node instanceof WorkExpectation)
461
+ found.add(node);
462
+ }
463
+ return found;
464
+ }
465
+ //# sourceMappingURL=orchestrator.js.map