@plurnk/plurnk-service 1.3.1 → 1.3.3
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/README.md +9 -0
- package/SPEC.md +49 -17
- package/dist/build-info.json +1 -1
- package/dist/core/ChannelWrite.d.ts +2 -1
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +7 -6
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts +31 -0
- package/dist/core/CoreSchemeServices.d.ts.map +1 -0
- package/dist/core/CoreSchemeServices.js +37 -0
- package/dist/core/CoreSchemeServices.js.map +1 -0
- package/dist/core/Dispatcher.d.ts +5 -2
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +115 -44
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/Engine.d.ts +4 -2
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +29 -10
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +1 -40
- package/dist/core/LiveSubscriptions.d.ts +8 -0
- package/dist/core/LiveSubscriptions.d.ts.map +1 -0
- package/dist/core/LiveSubscriptions.js +32 -0
- package/dist/core/LiveSubscriptions.js.map +1 -0
- package/dist/core/LoopLifecycle.d.ts +20 -0
- package/dist/core/LoopLifecycle.d.ts.map +1 -0
- package/dist/core/LoopLifecycle.js +56 -0
- package/dist/core/LoopLifecycle.js.map +1 -0
- package/dist/core/LoopLifecycle.sql +60 -0
- package/dist/core/ProposalLifecycle.d.ts +3 -1
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +4 -2
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +3 -0
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +23 -0
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +3 -2
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +20 -9
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +3 -16
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +4 -23
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/run-ops.sql +1 -1
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js +3 -4
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/schemes/Exec.d.ts +11 -10
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +40 -37
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +8 -6
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +11 -6
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +11 -9
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +24 -16
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +9 -7
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +12 -8
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Prompt.d.ts +0 -3
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +0 -5
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/Skill.d.ts +0 -5
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +0 -10
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/Worker.d.ts +12 -10
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +30 -28
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/server/Daemon.d.ts +9 -1
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +161 -74
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonLock.d.ts +7 -0
- package/dist/server/DaemonLock.d.ts.map +1 -0
- package/dist/server/DaemonLock.js +85 -0
- package/dist/server/DaemonLock.js.map +1 -0
- package/dist/server/clientTurn.d.ts.map +1 -1
- package/dist/server/clientTurn.js +2 -3
- package/dist/server/clientTurn.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +20 -2
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +4 -8
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +2 -3
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/lifecycle-recovery.sql +68 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +61 -40
- package/dist/service.js.map +1 -1
- package/migrations/0000-00-00.01_schema.sql +5 -5
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -51,3 +51,12 @@ Plurnk sees what git sees. The model's file surface is defined by three external
|
|
|
51
51
|
Run the root monorepo commands for deterministic lint, unit, and integration
|
|
52
52
|
coverage. Live-model, demo, and installation tests declare their external
|
|
53
53
|
requirements separately.
|
|
54
|
+
|
|
55
|
+
For manual client/service drills, create the modest standalone project used by
|
|
56
|
+
the demos instead of digesting this monorepo:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
npm run fixture:demo -w plurnk-core -- <label>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The command prints the temporary project path. The caller removes it when done.
|
package/SPEC.md
CHANGED
|
@@ -193,7 +193,7 @@ All three ride one engine seam — the daemon's inject (active→fold, idle→en
|
|
|
193
193
|
Beyond the three creation ops:
|
|
194
194
|
|
|
195
195
|
- **Entries (storage)** — entry addressing rides the authority carving above (§worker-authority-carving): `worker:///` the commons, `worker://~/` the own space, a name an ancestry-gated read (§worker-read-scope), writes self-and-commons only (§worker-write-scoping). An entry-path `KILL` deletes under the same write-scoping (200; 404 absent; 403 named) — distinct from the path-ABSENT `KILL(worker://<name>)` which terminates the worker (§worker-scheme-terminate); the discriminator is the entry path, never the op. A worker's own space is catalogued in ITS perspective alone (`FIND(worker://~/**)`, foisted at turn 0 when non-empty); isolation is the owner column, structural.
|
|
196
|
-
- **Terminate** — `KILL(worker://<name>)` aborts a worker by address (self is `worker://self`):
|
|
196
|
+
- **Terminate** — `KILL(worker://<name>)` aborts a worker by address (self is `worker://self`): every unresolved loop in that worker's subtree closes 499 and every subscription in the subtree tears down; a name with no worker is 404. Cancellation is structured: descendants cannot detach implicitly. The override to the fire-and-forget default is not a parent-power — whoever holds the address may end it; a worker left alone simply ends at its own `SEND[200]`. {§worker-scheme-terminate}
|
|
197
197
|
- **Cap** — `PLURNK_SERVICE_WORKSPACE_WORKERS_MAX_ACTIVE` ceilings the *concurrent* active workers per workspace (a worker with a non-terminal loop); a spawn or fork past it fails hard (508 — no queue, no retry), irc exempt; `-1` disables it. The fork-bomb brake, sized for workspaces that live for months. {§worker-scheme-cap}
|
|
198
198
|
- **Collect** — a worker's loop reaching a terminal status surfaces to its sisters as an ambient delta (§env-delta): a `SEND` from `worker://<name>` carrying the loop's deliverable — the `SEND[200]` body, or for an abandonment the reason. A **2xx deliverable is born OPEN** (its body materialized into the parent's packet, not hidden behind a fold): a child's success must reach the parent open and awakening, never a bodyless row. An abandonment (non-2xx) surfaces folded. Every death-path is stamped uniformly, so no termination is silent; collection is the shared world moving, never a verb. **Child orientation.** Beyond the conclusion delta, every turn the packet's status clump surfaces the live things THIS worker *currently holds* — open streams (`## Child Streams`) and unconcluded child workers (`## Active Child Workers`) — as terse `* <status> <path>` pointers (the same shape as the errors section), just above it. A worker is otherwise marked only at spawn and at conclusion; in between it goes silent, so a model loses track of what it holds and premature-terminates. This is ORIENTING STATE, never advice: the model SEES its live subtree (`* 102 worker://worker-x`, `* active sh:///1/2/3`) and reasons for itself — READ/OPEN/KILL via the path — the error stays terse. Empty → omitted, like errors. {§child-orientation} The **pull** side mirrors the push: a path-absent `READ(worker://<name>)` collects the same deliverable on demand — the latest loop's terminal message (the result, or the abandonment reason) for a concluded worker; a worker **still running** has not delivered, so the READ returns **425** (Too Early) and the turn's `SEND[202]` **blocks the loop on the join** ({§join-blocking-collect}) until the worker delivers — the engine holds the join, the model never drives a park. A missing name is 404. So the model never needs to guess a scratch path to "check on" a worker — reading the worker itself yields its outcome or a wait. {§worker-scheme-collect}
|
|
199
199
|
|
|
@@ -203,14 +203,29 @@ Beyond the three creation ops:
|
|
|
203
203
|
|
|
204
204
|
A worker is a **log plus a cancellation scope** — one `AbortController` per worker, reused while live and replaced only once aborted, so a cancel ends the worker as a unit and a later `loop.run` is never born cancelled. A worker's queued loops are advanced by a **drain**: a single per-worker worker that claims loops atomically (status 100→102) and runs each under the worker's scope. A loop may spawn **streams** (execs) that outlive it; each is a row in the subscription registry (§subscriptions) — the durable record of what the worker holds open. Cancellation and conclusion are defined against these structures, never wall-clock timing.
|
|
205
205
|
|
|
206
|
+
```mermaid
|
|
207
|
+
stateDiagram-v2
|
|
208
|
+
[*] --> Queued: loop.run
|
|
209
|
+
Queued --> Running: drain claims
|
|
210
|
+
Running --> Parked: wait with live obligations
|
|
211
|
+
Parked --> Queued: obligation settles or arrival
|
|
212
|
+
Running --> Terminal: conclude or fail
|
|
213
|
+
Parked --> Terminal: cancel
|
|
214
|
+
Queued --> Terminal: cancel
|
|
215
|
+
Terminal --> [*]
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The lifecycle store admits only the guarded transitions shown above: `100 → 102`, `102 → 202`, `202 → 100`, and any unresolved state (`100`, `102`, `202`) to a terminal status. Terminal state is immutable. The queue drain owns claim, the dispatcher owns model-requested park/conclusion, the daemon owns wake/cancellation/restart reconciliation, and the engine owns policy terminals. A racing transition that loses observes the durable winner; it does not overwrite it or report the requested state as fact. {§worker-lifecycle-state-machine}
|
|
219
|
+
|
|
206
220
|
- **One drain advances a worker.** At most one drain is registered for a worker at any instant: a `loop.run` or wake on a worker with a live drain folds in (active→next-turn) or enqueues a loop that drain claims, never a second parallel drain. A drain's start and its empty-queue teardown relinquish the worker under one per-worker lock, so the teardown's re-claim cannot race a concurrent start into a double-drain. {§worker-lifecycle-single-drain}
|
|
207
|
-
- **
|
|
221
|
+
- **Cancellation is recursive and reaps every held stream.** `loop.cancel`, worker `KILL`, shutdown, and a worker's `SEND[499]` terminalize every unresolved loop in the cancelled worker subtree and iterate each worker's durable open-subscription rows, invoking each exact callable owner from the process-local live registry. The durable rows answer *what is held*; the live registry answers *how this process tears it down*; the abort signal is a fast-path optimization. There is no implicit detachment. A stream that is running, mid-spawn (its row written before it is killable), or spawned after the cancel is reaped alike. The teardown abort is bounded: the executor sends a polite signal then SIGKILL after a consumer-set grace (`PLURNK_SERVICE_EXEC_KILL_GRACE_MS`). A model `KILL[code]` on one live stream instead delivers exactly that signal once (bare `KILL` → the executor's SIGHUP default, `KILL[9]` → SIGKILL). {§worker-lifecycle-total-reap}
|
|
208
222
|
- **A stream's kill binds to the scope it captured at spawn.** A stream captures the worker's cancellation scope as it registers and wires its kill to it, re-checking `aborted` AFTER wiring — no check-then-listen gap can drop an abort that lands mid-registration. Because the scope is replaced only once aborted, a captured-then-replaced scope is necessarily already aborted, so replacement never strands a live stream. {§worker-lifecycle-exec-epoch-bound}
|
|
209
223
|
- **A cancelled run is not resurrected by its own torn-down work.** A stream conclusion delivered to a cancelled, idle worker starts no fresh drain: an aborted (499) conclusion is skipped, and a straggler that concluded cleanly surfaces its deliverable as an environment delta (§env-delta), never a revived loop. The cancel was deliberate; only an explicit `loop.run` resumes the worker. {§worker-lifecycle-no-resurrection}
|
|
210
224
|
- **A stream conclusion always reaches its worker.** When a backgrounded stream concludes, the daemon routes it through the same inject seam as any loop source (§actor-boundary-passive-wake): an active worker folds the conclusion into its next turn; a worker **blocked on a 202 wait** for that stream (§wait-obligation-matrix) **awakens that loop in place** — the blocked loop *is* the continuation, so there is no fresh loop and no summary-as-prompt fiction. The result is never lost: a blocked loop sleeps rather than ending, and the stream's status-transition is the arrival (§actor-boundary-passive-wake) that wakes it; on resume it reads the concluded stream's own state, not a synthetic prompt. {§worker-lifecycle-wake-liveness}
|
|
211
225
|
- **A child worker concluding wakes a parent blocked on it — the topology join.** `worker://` spawn/fork records `parent_worker_id` (§lifecycle-terms). When a worker's drain exits having **concluded** — no `202`-blocked loop, no open stream — the daemon resumes its parent **in place** if the parent is blocked on the join (`#onDrainExit` → the shared `#wakeParkedWorker`, the same 202→100 resume a stream conclusion uses). So a parent that spawns work and blocks (`SEND[202]`) is woken the moment its child finishes; on resume it reads the child's deliverable from the §worker-scheme-collect delta in its own log — a control edge, **never an injected prompt**. The wake recurses upward via the parent's own drain-exit. A child still running — or itself blocked at 202 — is not *concluded*, so it does not wake the parent (it's still a live thing the subtree holds). This is the structured-concurrency join: streams and child workers are the same kind of "live thing a worker holds," driving premature-terminate (§send-premature-terminate), the wake edge, and the collect delta identically. A worker conclusion is a **bounded, un-loseable** wake: if the conclusion fires while the parent is mid-turn (before its block commits), `#wakeParkedWorker` finds it not-yet-slept and records an **owed wake**, which the drain honors when the parent blocks — so a wait awaiting workers **always returns**, never dead-blocks on a conclude-before-block race. (Only a live exec stream, unbounded absent a timeout, may legitimately hold a wait open.) {§worker-lifecycle-child-wake}
|
|
212
|
-
- **An idle run concludes; it does not park.** A loop with nothing in flight — no live child, no open stream — concludes
|
|
226
|
+
- **An idle run concludes; it does not park.** A loop with nothing in flight — no live child, no open stream — concludes through `SEND[200]` or an already-drained `SEND[202]` join (§wait-obligation-matrix). There is no held-open `202` loop and no `loop/quiesced` soft signal. A concluded worker is *already* reawakable — it is durable working history (§machine-processes-worker-is-its-log, engine_render_log spans the whole worker), and an addressed arrival (a sibling `irc`, an operator inject, a later `loop.run`) reawakens it as a **new loop** carrying that arrival's real prompt. Only a loop that holds a live obligation *blocks* (§wait-obligation-matrix, the `202+J` join); a subtree with any live thing under it is not idle, and that thing's conclusion reawakens the **same** loop with its prompt intact (§worker-lifecycle-child-wake). {§worker-lifecycle-idle-is-concluded}
|
|
213
227
|
- **A loop is never stranded by a drain's exit.** A drain relinquishes its registry slot only after a lock-held re-claim confirms the queue is empty; a loop enqueued during that teardown is either re-claimed by the exiting drain or claimed by a fresh drain that a later inject starts. The relinquish and the start are serialized, so neither the lost-loop hang nor a transient double-drain can occur. {§worker-lifecycle-no-lost-loop}
|
|
228
|
+
- **Restart is owner-loss reconciliation, not replay.** {§worker-lifecycle-restart-recovery} Before opening client transports, the service holds an exclusive database-adjacent daemon lock; a second live owner fails before touching SQLite, while a dead-PID crash claim is replaced atomically without a timeout lease. Boot preserves accepted `100` loops and restores their drains. A `102` loop belonged to a vanished drain/provider call, so it settles `500` with the interruption on its durable row—never replayed across an unknown effect boundary. Every durable-open subscription likewise belonged to a vanished callable: active channels become errored and its row closes `500`. A `202` continuation survives only while a live child obligation remains; after reconciliation, an unblocked park requeues `202→100` and resumes in place. Child terminalization wakes its parked parent on every outcome, including provider exceptions, cancellation, and restart interruption, recursively through the durable parent edges. These operations are idempotent, so an interrupted recovery safely repeats.
|
|
214
229
|
|
|
215
230
|
---
|
|
216
231
|
|
|
@@ -318,7 +333,7 @@ Per author contract (`readEntry` / `writeEntry` / `deleteEntry`). Engine drives
|
|
|
318
333
|
|
|
319
334
|
Per author contract (`edit`/`read`/`open`/`fold`/`find`/`send`/`exec?`). Engine dispatches by `PlurnkStatement.op`. {§op-methods-op-dispatch} COPY and MOVE are NOT scheme methods — engine orchestrates over CRUD primitives (§copy/§move).
|
|
320
335
|
|
|
321
|
-
- **Every op completes before the next begins — except the three concurrency-creators.** {§op-synchronous} Within a turn ops run in sequence, and each is *decisive*: its effect has fully landed by the time the next op — or the terminal gate — reads it. The dispatch `await`s each, so `KILL`, `EDIT`, `COPY`, `MOVE`, `READ` (including the blocking worker-collect, §worker-scheme-collect), `FIND`, `OPEN`, `FOLD` never leave work "in flight" for a later op to trip over. The ONLY exceptions are the ops whose *job* is to create concurrency and hand it back tracked: **FORK** and **WORK** (spawn a child worker) and **stream-producers** (`EXEC` and friends) return the instant the concurrent thing is launched and registered (the §child-orientation sections), never blocking the turn on its conclusion. This is
|
|
336
|
+
- **Every op completes before the next begins — except the three concurrency-creators.** {§op-synchronous} Within a turn ops run in sequence, and each is *decisive*: its effect has fully landed by the time the next op — or the terminal gate — reads it. The dispatch `await`s each, so `KILL`, `EDIT`, `COPY`, `MOVE`, `READ` (including the blocking worker-collect, §worker-scheme-collect), `FIND`, `OPEN`, `FOLD` never leave work "in flight" for a later op to trip over. The ONLY exceptions are the ops whose *job* is to create concurrency and hand it back tracked: **FORK** and **WORK** (spawn a child worker) and **stream-producers** (`EXEC` and friends) return the instant the concurrent thing is launched and registered (the §child-orientation sections), never blocking the turn on its conclusion. This is why a same-turn `KILL + SEND[200]` concludes (§send-premature-terminate): `KILL` synchronously flips the worker's live loops terminal (`engine_terminate_worker_live_loops`) so the gate sees it dead at once, while the physical scope reap rides `cancelWorker` asynchronously and invisibly. The obligation is the model's protection: it must never reason about whether its last decisive op has landed yet.
|
|
322
337
|
|
|
323
338
|
### §orchestration Cross-scheme orchestration
|
|
324
339
|
|
|
@@ -638,7 +653,7 @@ AST: `{ op: "SEND", target: ParsedPath | null, body: SendBody | null, signal: nu
|
|
|
638
653
|
- **Broadcast** (path null): the loop's disposition verb. `signal` is the model's *claim* about the worker's state — see the terminal contract.
|
|
639
654
|
- **Directed** (path non-null): routes to `scheme.send` per §send-dispatch — stream control / cross-worker irc, never a loop terminal.
|
|
640
655
|
|
|
641
|
-
**Terminal contract —
|
|
656
|
+
**Terminal contract — three signals over a structured-concurrency scope.** A broadcast SEND's status is a claim the engine **verifies against the worker's actual state**, never a verdict it trusts. The model signals one intention — **continue (102)**, **done (200)**, or **wait (202)** — plus **499**, give up. An **obligation** is live work the loop set going and has not consumed: **J**, a child or stream it spawned (the join), and **R**, this turn's own retrievals (READ/FIND/OPEN, whose results land next turn). `<T,P>` is an explicit timeout / poll override for external streaming work; ordinary child joins are event-driven and carry no polling fallback.
|
|
642
657
|
|
|
643
658
|
| intention | ∅ (no obligation) | J (live spawned work) | R (pending retrieval) |
|
|
644
659
|
|---|---|---|---|
|
|
@@ -646,9 +661,9 @@ AST: `{ op: "SEND", target: ParsedPath | null, body: SendBody | null, signal: nu
|
|
|
646
661
|
| **200** done | **resolved** — terminal, loop ends | **refused** — Premature-Terminate (KILL to abandon, or wait) | **refused** — forced next turn to see what you fetched |
|
|
647
662
|
| **202** wait | **resolves like 200** — a wait on zero things is satisfied; `<-1>+∅` is a bid to hang the agent, folded to done, never honored | **block on the join** — the loop sleeps (`<T>`/`<-1>` bound it, `<P>` polls); its work's conclusion **reawakens the same loop**, prompt intact (§worker-lifecycle-child-wake, §worker-lifecycle-wake-liveness) | resolves next turn (≈ continue) |
|
|
648
663
|
|
|
649
|
-
**499** gives up regardless of obligations — the model's one self-decided failure (§state-terms)
|
|
664
|
+
**499** gives up regardless of obligations and cancels the unresolved descendant scope — the model's one self-decided failure (§state-terms). The surface is small on purpose. The **one** non-obvious cell is **200 with an obligation in flight** — a contradiction (you claimed done while you owe work), which the engine holds you to via Premature-Terminate below. A child join is bounded by the child's terminal transition; an external stream may carry an explicit `<T,P>` policy. {§wait-obligation-matrix}
|
|
650
665
|
|
|
651
|
-
**An
|
|
666
|
+
**An externally-authored terminal is marked as state, never re-worded.** `terminated_by` names who ended a loop when the model did not: `'cancel'` for an externally-cancelled loop (§methods-loop-cancel); `NULL` = the model's own terminal, whose status already carries the story. COLLECT renders the named act as a marker before any preserved last words, so cancellation cannot masquerade as a deliverable. An already-drained join is the model's own successful terminal and needs no special marker.
|
|
652
667
|
|
|
653
668
|
The engine's failure terminals — **500** (strike threshold) and **508** (cycle), §engine-rails — are never the model's to pick; they are the engine ruling the loop failed. The surface is small on purpose: the model says done, waiting, or giving up, and is never asked to hold a correct opinion about *how* it failed or *whether* it can be woken — the engine decides those from state.
|
|
654
669
|
|
|
@@ -666,7 +681,7 @@ Engine routes unconditionally to `exec` scheme (the `(target)` slot is a local p
|
|
|
666
681
|
|
|
667
682
|
**Runtime fall-through** {§exec-runtime-fallthrough} — an UNREGISTERED runtime tag falls through to the shell with the tag as the command word: `EXEC[go]:test ./...` runs as sh's `go test ./...` (#350, the execs architect's dispatch spec automating the owner's execs#21 ruling: per-tool runtimes — go, cargo, make, npm — never earn tags; sh is the general answer). The fall-through rides sh's OWN policy gate (a workspace that disabled sh gets the refusal, never a side door), its output entry lands under `sh://` (it ran on sh, no phantom scheme), and telemetry records `exec_runtime_fallthrough {requested}` — which tags models reach FOR is the data that would ever justify a real runtime, never guesswork. A typo'd tag becomes the shell's own clear 127. No new surface: anything expressible as `EXEC[foo]:bar` was expressible as `EXEC[sh]:foo bar`. The 501 remains for a fall-through-ineligible dispatch (sh itself unregistered or workspace-disabled).
|
|
668
683
|
|
|
669
|
-
**Timeout and poll — `<T,P>` on the `<L>` slot (grammar 0.74.20).** EXEC repurposes the line-marker slot as `<timeout, poll>` in **seconds** (consistent with the `seconds=` stream-age render). `T` (mark[0]) caps the spawn's lifetime: at `T>0` the service aborts it (a bounded reap — polite signal then SIGKILL after `PLURNK_SERVICE_EXEC_KILL_GRACE_MS`) and stamps the stream **504**, distinct from a deliberate kill (499) or a clean exit (200). `-1` / absent → unbounded (loop-life bounded), the background-stream behavior. **`0` → turn-scoped**: the stream is reaped at the worker's *next pre-turn* (via the registry abort, before the turn's own spawns), so it never survives into the subsequent turn; its terminal output surfaces born-OPEN like any close (§exec-stream). {§exec-timeout} `P` (mark[1]) is the **poll cadence**, stored on the subscription: while the loop is *blocked on a `SEND[202]` wait* for that stream
|
|
684
|
+
**Timeout and poll — `<T,P>` on the `<L>` slot (grammar 0.74.20).** EXEC repurposes the line-marker slot as `<timeout, poll>` in **seconds** (consistent with the `seconds=` stream-age render). `T` (mark[0]) caps the spawn's lifetime: at `T>0` the service aborts it (a bounded reap — polite signal then SIGKILL after `PLURNK_SERVICE_EXEC_KILL_GRACE_MS`) and stamps the stream **504**, distinct from a deliberate kill (499) or a clean exit (200). `-1` / absent → unbounded (loop-life bounded), the background-stream behavior. **`0` → turn-scoped**: the stream is reaped at the worker's *next pre-turn* (via the registry abort, before the turn's own spawns), so it never survives into the subsequent turn; its terminal output surfaces born-OPEN like any close (§exec-stream). {§exec-timeout} `P` (mark[1]) is the **poll cadence**, stored on the subscription: while the loop is *blocked on a `SEND[202]` wait* for that stream, the daemon arms a per-worker timer for the tightest open poll cadence and resumes the blocked loop every P seconds (floored by `PLURNK_SERVICE_EXEC_WAIT_MS` so it cannot tick faster than a turn settles) to inspect progress. It does **nothing while the loop is active** because ambient stream deltas already surface progress. An open stream without `P` uses exponential backoff (`PLURNK_SERVICE_EXEC_POLL_SEC` and `PLURNK_SERVICE_EXEC_POLL_TURNS`); explicit `<,P>` wins and `<,0>` disables polling. Child-only joins never use this timer: child settlement is their durable wake edge. {§exec-poll}
|
|
670
685
|
|
|
671
686
|
**Effect-gating.** Each executor declares an `effect` (`pure` | `read` | `host`); the service maps it to policy (`EffectPolicy`). A `host` runtime (subprocess; file-backed sqlite) mutates the host → **propose** (lifecycle §proposal): the worker waits for a human gate, then spawns and writes stdout/stderr to channels of a `<runtime>:///<loop>/<turn>/<seq>` entry (the runtime tag is the URI scheme, §exec/#240; the coordinate matches the op's log-row coordinate, e.g. `sh:///1/1/2`), returning `102 Processing` immediately. Channel state transitions (`active` → `closed`/`errored`) drive what the model sees at subsequent turn boundaries (§channel-state). {§exec-host-proposes}
|
|
672
687
|
|
|
@@ -716,9 +731,14 @@ Streams are static content from the engine's perspective — content arrives ove
|
|
|
716
731
|
|
|
717
732
|
### §subscriptions Subscriptions
|
|
718
733
|
|
|
719
|
-
READ on a streaming scheme is a subscription, not a one-shot. Scheme opens the connection (SSE/WS/subprocess), returns `102 Processing` immediately, stays alive.
|
|
734
|
+
READ on a streaming scheme is a subscription, not a one-shot. Scheme opens the connection (SSE/WS/subprocess), returns `102 Processing` immediately, stays alive. The service records durable subscription identity and metadata in SQLite and retains the callable `SubscriptionHandle` only in its process-local live registry. `SEND[499]`, worker cancellation, turn-scoped reap, and shutdown all route through that one live registry; no handler-specific cancellation hook or database access is part of the plugin contract. {§subscriptions-subscription-registry-routes-cancellation}
|
|
735
|
+
|
|
736
|
+
The durable row is lifecycle evidence and the lookup key, not a serialized callback. `subscriptions.open()` establishes both halves before yielding; `subscriptions.close("done" | "error" | "cancelled")` settles channel state and status (200/500/499), closes the durable row, wakes the worker when appropriate, and unregisters the live handle. A durable open row without a live handle is an explicit lifecycle failure, never a fabricated cancellation success. Channel state (§channel-state) + log entries (§no-chunk-rows) carry lifecycle.
|
|
720
737
|
|
|
721
|
-
|
|
738
|
+
At process restart every still-open row is necessarily missing its callable owner. Boot
|
|
739
|
+
settles it as interruption (`500`) and errors active channels before evaluating parked
|
|
740
|
+
loops (§worker-lifecycle-restart-recovery); it never reports cancellation (`499`) or
|
|
741
|
+
pretends to reconstruct an opaque plugin connection.
|
|
722
742
|
|
|
723
743
|
FOLD/OPEN toggles `log_entries.expanded` (§open-fold) — a per-worker render bit, never the subscription registry. FOLDing a streaming entry's log row collapses its body out of the packet but leaves the live stream running: curation is render-only, never cancellation. {§subscriptions-fold-keeps-subscription}
|
|
724
744
|
|
|
@@ -738,7 +758,7 @@ Model sees lifecycle events in the `log` section per turn.
|
|
|
738
758
|
|
|
739
759
|
### §stream-control SEND for stream control
|
|
740
760
|
|
|
741
|
-
- **Cancel:** `<<SEND[499](sse://feed/x)::SEND` —
|
|
761
|
+
- **Cancel:** `<<SEND[499](sse://feed/x)::SEND` — the service invokes the handle registered by `subscriptions.open()` and aborts the composed subscription signal.
|
|
742
762
|
- **Write:** `<<SEND[200](wss://feed/x):body:SEND` — pipes body into active connection (WS, exec stdin, etc.).
|
|
743
763
|
|
|
744
764
|
### §stream-constraints Engine constraints
|
|
@@ -1006,7 +1026,7 @@ registry.registerMethod("loop.run", {
|
|
|
1006
1026
|
| `loop.run` | `prompt: string`, `maxTurns?: number`, `alias?: string`, `model?: string`, `flags?: LoopFlags` | `{ loopId, action, finalStatus: 100 }` | Model-driven loop. **Accepts and returns immediately** (`finalStatus: 100`; `action` = `enqueued_new_loop` \| `injected_next_turn`) — it never blocks on the loop, which may block on a `SEND[202]` wait for its own spawned work (§worker-lifecycle-wake-liveness). The loop's outcome — `finalStatus`, `turnIds`, `hitMaxTurns`, `usage` — arrives on the **`loop/terminated`** event. **Per-loop model selection** (#414/#598): optional `model` (client-resolved `<provider>/<model>`, wins) or `alias` (a declared `PLURNK_MODEL_<alias>`) overrides the boot-time `PLURNK_MODEL` for a newly created loop. The fully resolved `{ alias, provider, model, baseUrl? }` is persisted on that loop and is immutable through every turn, queue claim, async wake, and daemon restart; no resume path may substitute the boot default. A prompt folded into an active or parked loop must resolve to the same selection; a conflicting selection fails loudly and requires the caller to conclude or cancel before opening a loop on another model. Provider instances are cached, an unresolvable spec fails before enqueue, and neither selector runs the boot default. Mid-loop switching is not an implicit side effect of prompt injection; a future such capability requires its own explicit atomic operation. Optional `flags` carries per-loop flags (`{auto?: boolean}`; see §engine-rails). Streams `log/entry` and `loop/proposal` during. `longRunning: false`. {§methods-loop-run} {§methods-loop-run-model} |
|
|
1007
1027
|
| `proposal.list` | — | `{ proposals: [{logEntryId, workerId, loopId, turnId, op, suffix, target, body, attrs, flags, at}] }` | Every pending (`state='proposed'`) stop-the-world proposal in the attached workspace — the indefinite-wait ruling's mandatory companion: `loop/proposal` is a notification, so a client reconnecting during a stopped world (possibly days old) DISCOVERS it here and answers via the ordinary `loop.resolve`. `attrs` carries `{question, choices}` for [300] asks. {§proposal-list} |
|
|
1008
1028
|
| `loop.resolve` | `logEntryId: number`, `decision: "accept" \| "reject" \| "cancel"`, `body?: string`, `outcome?: string` | `{ status, logEntryId }` | Resolve a pending proposal (status=202 log entry). Engine.dispatch unpauses on resolution. |
|
|
1009
|
-
| `loop.cancel` | `reason?: string` | `{ cancelled, workerId, reason }` |
|
|
1029
|
+
| `loop.cancel` | `reason?: string` | `{ cancelled, workerId, reason }` | Cancel the attached worker's structured scope. Every unresolved loop (`100`, `102`, or `202`) in the worker subtree closes at 499 and every held subscription is reaped; descendants never detach implicitly. Default reason `user_cancelled`. `cancelled` reports whether the attached worker had process-local work when the request arrived; durable parked or queued work is still terminalized when it is `false`. Cancellation is provenanced: each affected row records `terminated_by='cancel'` and the reason, and each terminal event carries the same message. {§methods-loop-cancel} |
|
|
1010
1030
|
| `providers.list` | none | `{ aliases: ProviderAlias[] }` | Lists configured `PLURNK_MODEL_<alias>` entries with `{alias, provider, model, active}`. Clients use to populate model-selection UI. |
|
|
1011
1031
|
|
|
1012
1032
|
**Reads**
|
|
@@ -1022,7 +1042,10 @@ registry.registerMethod("loop.run", {
|
|
|
1022
1042
|
|
|
1023
1043
|
Per the **Speak in DSL, not plumbing** rule (AGENTS.md): `op.*` methods construct DSL statements internally and dispatch through `Engine.dispatch`. {§methods-op-mirror} Param shapes are ergonomic (semantic names, not HEREDOC slots); semantics are the DSL's.
|
|
1024
1044
|
|
|
1025
|
-
Each
|
|
1045
|
+
Each client action creates one terminal journal segment (§connection-lifecycle). Every
|
|
1046
|
+
statement in that action creates an ordered turn inside the segment, dispatches, fires
|
|
1047
|
+
`log/entry`, and returns its result. `op.parse` therefore does not manufacture one loop
|
|
1048
|
+
per parsed statement.
|
|
1026
1049
|
|
|
1027
1050
|
Naming: `target` = URI the op acts on; `scope` for FIND; `source`/`destination` for COPY/MOVE; `recipient` for SEND (or null = broadcast); `cwd` for EXEC. `path` is reserved for *identity* — never an RPC operand.
|
|
1028
1051
|
|
|
@@ -1052,7 +1075,7 @@ Future: `subscription.list`, `subscription.cancel` (the latter is `op.send({stat
|
|
|
1052
1075
|
| Notification | Params | When fired |
|
|
1053
1076
|
|--------------------|-------------------------------------|------------|
|
|
1054
1077
|
| `log/entry` | `{ entry: LogEntry }` | Every `log_entries` write. {§notifications-log-entry-notify} |
|
|
1055
|
-
| `loop/terminated` | `{ loopId, finalStatus, hitMaxTurns }` |
|
|
1078
|
+
| `loop/terminated` | `{ workerId, loopId, finalStatus, hitMaxTurns, turnIds, usage, message? }` | One loop reaches terminal status. `workerId` and `loopId` are an inseparable owning coordinate; transports bind completion to the exact loop they started or resumed and never infer either half from workspace traffic. |
|
|
1056
1079
|
| `loop/proposal` | `{ logEntryId, workspaceId, workerId, loopId, turnId, op, target, body, attrs, flags }` | Dispatch pauses on status=202. Carries `flags` so a client can suppress review UI when loop-owned policy will resolve it. Client responds with `loop.resolve` when authority crosses the boundary (or `PLURNK_SERVICE_PROPOSAL_TIMEOUT_MS` fires). |
|
|
1057
1080
|
| `workspace/created` | `{ id, name, projectRoot }` | Any client creates a workspace. |
|
|
1058
1081
|
| `stream/event` | `{ entryId, channel, state, contentLength }` | Channel content grows or state transitions. {§notifications-stream-event-on-channel-change} |
|
|
@@ -1063,7 +1086,16 @@ Future: `subscription.list`, `subscription.cancel` (the latter is `op.send({stat
|
|
|
1063
1086
|
|
|
1064
1087
|
### §connection-lifecycle Client context
|
|
1065
1088
|
|
|
1066
|
-
**
|
|
1089
|
+
**Client action evidence.** A module client is an actor (§machine-processes); its
|
|
1090
|
+
side-effecting `op.*` actions write to its **own worker** with `origin = "client"`.
|
|
1091
|
+
One action owns one journal segment, and all statements parsed from that action are
|
|
1092
|
+
ordered turns inside it. A proposal may hold the segment open while the action crosses
|
|
1093
|
+
an AG-UI interrupt/resume boundary; resolution or failure closes it. These segments
|
|
1094
|
+
record durable action evidence but do not define client-visible lifecycle—AG-UI runs do.
|
|
1095
|
+
Observational actions create no turns or rows. `LOOK` retains a closed, rowless
|
|
1096
|
+
observation segment because the public scheme context and relative `log:///` addressing
|
|
1097
|
+
require an honest numeric loop coordinate; it never leaves active lifecycle behind.
|
|
1098
|
+
Multiple client actors have distinct workers.
|
|
1067
1099
|
|
|
1068
1100
|
`loop.run` and `inject` target the **model's worker** — a separate worker holding the conversation, `origin = "model"`. Both workers share the workspace's one filesystem (§machine-processes); the packet renders only the model's worker, so the client's ops are structurally absent from it — no origin filter (§actor-boundary-isolation). The model worker (`Envelope.ensureModelWorker`) and the client context's worker are distinct, each lazily allocated on first use.
|
|
1069
1101
|
|
|
@@ -1188,7 +1220,7 @@ The CAS is the **hard backstop**, at the moment of writing, on every accept path
|
|
|
1188
1220
|
- **One rule, every turn: fold the NEWEST memories — never history.** THE DOCTRINE, the project's animating narrative: the log is the model's memory and the model ALONE curates it (FOLD/KILL). The grinder never reaches back into history — it only blocks NEW memories from landing when there is no room, forcing the model to do its own housekeeping. On overflow it folds, in one set-op, the still-open rows of the **newest turn boundary**: the immediately-prior turn's emissions and the current turn's pre-model rows (foists, wake surfaces — every current-turn row at grind time is engine-written). Turn 1 is the **same rule**, not a case: no prior turn exists, so its own foists are the newest material. Folded, not deleted: rows and bodies persist and are re-OPENable, so log *history* is preserved while the render collapses to coordinates. {§grinder-layer1-rollback}
|
|
1189
1221
|
- **Errors, the prompt, AND the plan are exempt.** The grinder never folds an `op='error'` row (the budget-overflow it just minted, a parse failure, an action failure) — errors are the model's durable, curatable record of what went wrong; folding them the moment they matter would blind it to a recurring failure. Nor does it fold the **user prompt** (`plurnk:///prompt/…`, #382): the task the engine foisted is FRAME, not the model's curatable memory — the engine never reclaims the definition of the task it set. Nor a **PLAN row** (#465, owner ruling): the checklist is the model's orientation surface at exactly the moment the grinder fires — folding the plan alongside the work it plans would collapse the reasoning thread a recovery turn steers by, and plans are concise by rule, so exempting them reclaims almost nothing. All three stay OPEN until the model itself FOLDs or KILLs them. {§grinder-errors-exempt}
|
|
1190
1222
|
- **The hard overflow is a RECOVERY TURN first** {§grinder-hard-413-recovery} — (Q4, owner ruling: recoverable strike, NO margin). The overflow lives in foldable HISTORY the model owns, and the grinder never touches history (§grinder-layer1-rollback) — so the first hard overflow, when the packet is over the POLICY ceiling but still within PHYSICS (the provider's real window minus the decode reserve), is sent ANYWAY, once: a minted `budget_overflow` steer states the fact, the remedy (KILL/FOLD history; the budget table lists the heaviest), and the consequence — and the turn counts a strike (`budgetStruck`). The model curates → the next fitting turn clears the grant (a later overflow earns a fresh recovery; chronic overflow still strikes out via the rail). A recovery turn that CONCLUDES is a legitimate 200 — finishing is a way to stop overflowing. **No 95% margin**: the pointer fires at 100% of budget — a margin masks the signal, and the decode is separately reserved.
|
|
1191
|
-
- **Hard stop.** A physically-unsendable packet (over the provider's real window too — physics doesn't negotiate), or a SECOND consecutive hard overflow after the recovery turn (the model was told and declined), abandons the loop at **413 Content Too Large
|
|
1223
|
+
- **Hard stop.** A physically-unsendable packet (over the provider's real window too — physics doesn't negotiate), or a SECOND consecutive hard overflow after the recovery turn (the model was told and declined), abandons the loop at **413 Content Too Large**. Its sibling engine-imposed terminals are HTTP-precise too: `maxTurns` → 429, a strike-out → 500 (508 when cycle-driven) — no longer the old catch-all 499. No further passes. {§grinder-hard-413-abort}
|
|
1192
1224
|
|
|
1193
1225
|
- **Output truncation states its cause** {§tokenomics-output-truncated} — a `finish=length` turn was guillotined at the decode pool (`REASONING + COMPLETION`, one undifferentiated `max_tokens` — §tokenomics-window-partition), and its parse errors are truncation ARTIFACTS: without the cause stated, the model reads "unclosed block" and fixes syntax forever instead of emitting less (run29: unclamped cloud reasoning + a 9-edit emission vs a 12288 pool; the binding cap was plurnk's own — `completion 12281`). One terse `output_truncated` row (413) leads the artifact rows it explains, naming the cap and distinguishing its two shapes so the model reads the right cause: content cut **mid-op** (the severed frame — see {§broken-packet-no-dispatch}) vs the pool consumed with **nothing emitted** (reasoning ran away — the parse `must begin with PLAN` is an artifact of the empty emission, not a malformed turn). The row states the fact, not a remedy.
|
|
1194
1226
|
|
|
@@ -1500,7 +1532,7 @@ Carried from the contract walk; durable.
|
|
|
1500
1532
|
- **READ rx** prefixes each line with `N:` per §render-rule. `sliceLinesRaw` (used by COPY) returns the lines without prefix.
|
|
1501
1533
|
- **FIND body matcher** applies to entry content (all dialects), per-candidate via the in-tree `Matcher.matchAgainstContent` (§matcher-dispatch; status 200 = content hit → entry selected). Scope + tags select candidates in SQL; the path-glob is the (target).
|
|
1502
1534
|
- **OPEN/FOLD** operate on the **log** (`log:///`), not entries (§open-fold) — FOLD collapses a log row to its path, OPEN restores its body. Aimed at an entry scheme they return 501.
|
|
1503
|
-
- **SEND[410]** deletes as a side-effect (not the model idiom; §move): with `#fragment`, that channel only; without, the whole entry. **SEND[499]**
|
|
1535
|
+
- **SEND[410]** deletes as a side-effect (not the model idiom; §move): with `#fragment`, that channel only; without, the whole entry. **SEND[499]** resolves the durable open-subscription row and invokes that subscription's exact callable owner through the process-local live registry (§subscriptions).
|
|
1504
1536
|
- **File scheme** reads disk content with mimetype detected via `Mimetypes.detect({ path })` (plumbed through `PlurnkSchemeContext.mimetypes`). Binary mimetypes → 415 on READ and EDIT.
|
|
1505
1537
|
|
|
1506
1538
|
### §send-status-policy Directed-SEND status code policy
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"package":"@plurnk/plurnk-service","version":"1.3.
|
|
1
|
+
{"package":"@plurnk/plurnk-service","version":"1.3.2","revision":"535b20fb8e1980ab2bdcc79ab7b7389942970c97","dirty":false}
|
|
@@ -41,7 +41,8 @@ export type InjectWorkerNotify = (args: {
|
|
|
41
41
|
action: "injected_next_turn" | "enqueued_new_loop";
|
|
42
42
|
loopId: number;
|
|
43
43
|
}>;
|
|
44
|
-
export type CancelWorkerNotify = (workerId: number) =>
|
|
44
|
+
export type CancelWorkerNotify = (workerId: number, reason: string) => Promise<void>;
|
|
45
|
+
export type CancelDescendantsNotify = (workerId: number, reason: string) => Promise<void>;
|
|
45
46
|
export interface TelemetryEventPayload {
|
|
46
47
|
loopId: number;
|
|
47
48
|
event: object;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAMtE,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAQzF,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAUpE,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IAMf,KAAK,CAAC,EAAE,SAAS,CAAC;CACrB,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAOtF,MAAM,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
|
|
@@ -55,8 +55,10 @@ export default class ChannelWrite {
|
|
|
55
55
|
return;
|
|
56
56
|
notify(meta.workspace_id, { entryId, target: ChannelWrite.#targetUri(meta.scheme, meta.pathname), channel, state: meta.state, contentLength: meta.contentLength, mimetype: meta.mimetype, ...coordinate });
|
|
57
57
|
}
|
|
58
|
-
// The
|
|
59
|
-
//
|
|
58
|
+
// The durable half of subscription ownership. Its row identifies what is
|
|
59
|
+
// open; the process-local LiveSubscriptions registry owns the exact callable
|
|
60
|
+
// used by SEND[499] / KILL.
|
|
61
|
+
// §subscriptions-subscription-registry-routes-cancellation
|
|
60
62
|
static async openSubscription(db, { workerId, entryId, scheme, handle, pollSeconds, turnScoped, publishedChannel }) {
|
|
61
63
|
const row = await ChannelWrite.#openSubStmt(db).get({
|
|
62
64
|
worker_id: workerId, entry_id: entryId, scheme, handle,
|
|
@@ -82,10 +84,9 @@ export default class ChannelWrite {
|
|
|
82
84
|
return row ?? null;
|
|
83
85
|
}
|
|
84
86
|
// The worker's still-open subscriptions — the registry-routed reap
|
|
85
|
-
// (§worker-lifecycle-total-reap). A cancel iterates these
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
// signal an optimization.
|
|
87
|
+
// (§worker-lifecycle-total-reap). A cancel iterates these durable identities
|
|
88
|
+
// and invokes each exact callable through LiveSubscriptions, so a
|
|
89
|
+
// backgrounded exec is reaped regardless of AbortSignal-listener timing.
|
|
89
90
|
static async findOpenSubscriptionsForWorker(db, workerId) {
|
|
90
91
|
return ChannelWrite.#openSubsForWorkerStmt(db).all({ worker_id: workerId });
|
|
91
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,sFAAsF;AACtF,EAAE;AACF,mFAAmF;AACnF,4FAA4F;AAC5F,8EAA8E;AAC9E,6EAA6E;AAC7E,gCAAgC;AAIhC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Db } from "./Db.ts";
|
|
2
|
+
import type { Mimetypes } from "@plurnk/plurnk-mimetypes";
|
|
3
|
+
import type ExecutorRegistry from "./ExecutorRegistry.ts";
|
|
4
|
+
import type { InjectWorkerNotify, StreamEventNotify, WakeWorkerNotify } from "./ChannelWrite.ts";
|
|
5
|
+
import type { TelemetryEvent } from "./results.ts";
|
|
6
|
+
import type { PlurnkSchemeContext } from "./scheme-types.ts";
|
|
7
|
+
import type { SchemeCtx } from "@plurnk/plurnk-schemes";
|
|
8
|
+
import type LiveSubscriptions from "./LiveSubscriptions.ts";
|
|
9
|
+
export interface CoreSchemeServices {
|
|
10
|
+
readonly db: Db;
|
|
11
|
+
readonly mimetypes: Mimetypes;
|
|
12
|
+
readonly executors: () => ExecutorRegistry | undefined;
|
|
13
|
+
readonly tokenize: (text: string) => number;
|
|
14
|
+
readonly streamEventNotify: StreamEventNotify | undefined;
|
|
15
|
+
readonly wakeWorkerNotify: WakeWorkerNotify | undefined;
|
|
16
|
+
readonly injectWorker: InjectWorkerNotify | undefined;
|
|
17
|
+
readonly pushTelemetry: (workspaceId: number, loopId: number, event: TelemetryEvent) => void;
|
|
18
|
+
readonly defaultChannelFor: (scheme: string | null) => string;
|
|
19
|
+
readonly liveSubscriptions: LiveSubscriptions;
|
|
20
|
+
}
|
|
21
|
+
export interface CoreSchemeAdapter {
|
|
22
|
+
bindCore(services: CoreSchemeServices): void;
|
|
23
|
+
}
|
|
24
|
+
export type CoreSchemeCallContext = SchemeCtx | PlurnkSchemeContext;
|
|
25
|
+
export declare abstract class CoreSchemeAdapterBase implements CoreSchemeAdapter {
|
|
26
|
+
#private;
|
|
27
|
+
bindCore(services: CoreSchemeServices): void;
|
|
28
|
+
protected coreContext(ctx: CoreSchemeCallContext): PlurnkSchemeContext;
|
|
29
|
+
protected liveSubscriptions(): LiveSubscriptions;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=CoreSchemeServices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoreSchemeServices.d.ts","sourceRoot":"","sources":["../../src/core/CoreSchemeServices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7F,QAAQ,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;IAC9D,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;CACjD;AAED,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAMD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAEpE,8BAAsB,qBAAsB,YAAW,iBAAiB;;IAGpE,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAE3C;IAED,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,qBAAqB,GAAG,mBAAmB,CAqBrE;IAED,SAAS,CAAC,iBAAiB,IAAI,iBAAiB,CAI/C;CACJ"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class CoreSchemeAdapterBase {
|
|
2
|
+
#services;
|
|
3
|
+
bindCore(services) {
|
|
4
|
+
this.#services = services;
|
|
5
|
+
}
|
|
6
|
+
coreContext(ctx) {
|
|
7
|
+
if ("db" in ctx)
|
|
8
|
+
return ctx;
|
|
9
|
+
const services = this.#services;
|
|
10
|
+
if (services === undefined)
|
|
11
|
+
throw new Error(`${this.constructor.name}: core services are not bound`);
|
|
12
|
+
return {
|
|
13
|
+
db: services.db,
|
|
14
|
+
workspaceId: ctx.workspaceId,
|
|
15
|
+
workerId: ctx.workerId,
|
|
16
|
+
loopId: ctx.loopId,
|
|
17
|
+
turnId: ctx.turnId,
|
|
18
|
+
writer: ctx.writer,
|
|
19
|
+
signal: ctx.signal,
|
|
20
|
+
streamEventNotify: services.streamEventNotify,
|
|
21
|
+
wakeWorkerNotify: services.wakeWorkerNotify,
|
|
22
|
+
injectWorker: services.injectWorker,
|
|
23
|
+
mimetypes: services.mimetypes,
|
|
24
|
+
executors: services.executors(),
|
|
25
|
+
tokenize: services.tokenize,
|
|
26
|
+
defaultChannelFor: services.defaultChannelFor,
|
|
27
|
+
pushTelemetry: (event) => services.pushTelemetry(ctx.workspaceId, ctx.loopId, event),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
liveSubscriptions() {
|
|
31
|
+
const services = this.#services;
|
|
32
|
+
if (services === undefined)
|
|
33
|
+
throw new Error(`${this.constructor.name}: core services are not bound`);
|
|
34
|
+
return services.liveSubscriptions;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=CoreSchemeServices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoreSchemeServices.js","sourceRoot":"","sources":["../../src/core/CoreSchemeServices.ts"],"names":[],"mappings":"AAgCA,MAAM,OAAgB,qBAAqB;IACvC,SAAS,CAAiC;IAE1C,QAAQ,CAAC,QAA4B;QACjC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC9B,CAAC;IAES,WAAW,CAAC,GAA0B;QAC5C,IAAI,IAAI,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,+BAA+B,CAAC,CAAC;QACrG,OAAO;YACH,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;YAC7C,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;YAC3C,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE;YAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;YAC7C,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;SACvF,CAAC;IACN,CAAC;IAES,iBAAiB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,+BAA+B,CAAC,CAAC;QACrG,OAAO,QAAQ,CAAC,iBAAiB,CAAC;IACtC,CAAC;CACJ"}
|
|
@@ -6,7 +6,8 @@ import type ExecutorRegistry from "./ExecutorRegistry.ts";
|
|
|
6
6
|
import type TelemetryChannel from "./TelemetryChannel.ts";
|
|
7
7
|
import type ProposalLifecycle from "./ProposalLifecycle.ts";
|
|
8
8
|
import type { WriterTier } from "./scheme-types.ts";
|
|
9
|
-
import type
|
|
9
|
+
import { type StreamEventNotify, type WakeWorkerNotify, type InjectWorkerNotify, type CancelWorkerNotify, type CancelDescendantsNotify } from "./ChannelWrite.ts";
|
|
10
|
+
import type LiveSubscriptions from "./LiveSubscriptions.ts";
|
|
10
11
|
export type DispatchContext = {
|
|
11
12
|
statement: PlurnkStatement;
|
|
12
13
|
workspaceId: number;
|
|
@@ -25,7 +26,7 @@ export type DispatchResult = {
|
|
|
25
26
|
};
|
|
26
27
|
export default class Dispatcher {
|
|
27
28
|
#private;
|
|
28
|
-
constructor({ db, schemes, mimetypes, tokenize, telemetry, proposals, executors, loopSignal, streamEventNotify, wakeWorkerNotify, injectWorker, cancelWorker, searchGate, parkDeadlines, joinTargets }: {
|
|
29
|
+
constructor({ db, schemes, mimetypes, tokenize, telemetry, proposals, executors, loopSignal, streamEventNotify, wakeWorkerNotify, injectWorker, cancelWorker, cancelDescendants, searchGate, parkDeadlines, joinTargets, liveSubscriptions }: {
|
|
29
30
|
db: Db;
|
|
30
31
|
schemes: SchemeRegistry;
|
|
31
32
|
mimetypes: Mimetypes;
|
|
@@ -38,9 +39,11 @@ export default class Dispatcher {
|
|
|
38
39
|
wakeWorkerNotify?: WakeWorkerNotify;
|
|
39
40
|
injectWorker?: InjectWorkerNotify;
|
|
40
41
|
cancelWorker?: CancelWorkerNotify;
|
|
42
|
+
cancelDescendants?: CancelDescendantsNotify;
|
|
41
43
|
parkDeadlines?: Map<number, number>;
|
|
42
44
|
searchGate?: import("./search-gate.ts").default;
|
|
43
45
|
joinTargets?: Set<number>;
|
|
46
|
+
liveSubscriptions: LiveSubscriptions;
|
|
44
47
|
});
|
|
45
48
|
dispatch(context: DispatchContext): Promise<DispatchResult>;
|
|
46
49
|
look(context: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../../src/core/Dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAmD,MAAM,wBAAwB,CAAC;AAC/G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAE9C,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAC;AAQ5D,OAAO,KAAK,EAAkB,UAAU,EAAkC,MAAM,mBAAmB,CAAC;AAEpG,
|
|
1
|
+
{"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../../src/core/Dispatcher.ts"],"names":[],"mappings":"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"}
|