@orkestrel/scaffold 0.0.92 → 0.0.93
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/dist/bin/main.js +6 -6
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +4 -2
- package/dist/host/agents/skills/enterprise-bootstrap/references/responsive-layout.md +1 -1
- package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +1 -1
- package/dist/host/claude/agents/orkestrel.md +5 -5
- package/dist/host/claude/rules/styles.md +5 -0
- package/dist/host/dotfiles/oxlintrc.json +168 -0
- package/dist/host/guides/browser.md +94 -70
- package/dist/host/guides/mcp.md +15 -15
- package/dist/host/guides/pool.md +73 -48
- package/dist/host/guides/probe.md +262 -216
- package/dist/host/guides/router.md +1 -1
- package/dist/host/guides/worker.md +43 -7
- package/dist/host/manifest.json +15 -15
- package/dist/host/tests/config.test.ts +46 -3
- package/dist/src/core/index.cjs +6 -6
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +6 -6
- package/dist/src/core/index.js.map +1 -1
- package/package.json +6 -6
package/dist/host/guides/pool.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Pool
|
|
2
2
|
|
|
3
3
|
> A typed resource pool with optional bounded capacity, a warm floor, bounded loss recovery,
|
|
4
|
-
>
|
|
4
|
+
> exclusive leases by default, FIFO settlement, validated idle reuse, caller-owned cancellation, and explicit cleanup.
|
|
5
5
|
|
|
6
6
|
The pool supports lazy creation or a warm floor, with no eviction timer, acquire timeout,
|
|
7
7
|
or polling loop. Waits park on promises or signal listeners. An acquire rejects with
|
|
8
|
-
`cleanup` when a floor retains a record, owns `min` records, has nothing
|
|
8
|
+
`cleanup` when a floor retains a record, owns `min` records, has nothing eligible, and has no
|
|
9
9
|
refill or disposal pending, even with live leases. The lifecycle hooks are the caller's,
|
|
10
10
|
so the engine itself performs no I/O.
|
|
11
11
|
|
|
@@ -39,9 +39,9 @@ try {
|
|
|
39
39
|
|
|
40
40
|
### Factories
|
|
41
41
|
|
|
42
|
-
| API | Kind | Summary
|
|
43
|
-
| ------------ | -------- |
|
|
44
|
-
| `createPool` | function | Creates a distinct `PoolInterface` from resource lifecycle hooks, with optional bounded capacity,
|
|
42
|
+
| API | Kind | Summary |
|
|
43
|
+
| ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| `createPool` | function | Creates a distinct `PoolInterface` from resource lifecycle hooks, with optional bounded capacity, exclusive leases by default, and FIFO settlement. |
|
|
45
45
|
|
|
46
46
|
### Classes
|
|
47
47
|
|
|
@@ -57,27 +57,29 @@ In a guard table a `Shape` cell holds the type the guard narrows to.
|
|
|
57
57
|
| API | Kind | Shape | Summary |
|
|
58
58
|
| -------------- | -------- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
59
59
|
| `isPoolError` | function | `PoolError` | Tests whether an unknown value is a `PoolError`, returning `false` for hostile proxies. |
|
|
60
|
-
| `
|
|
60
|
+
| `isPoolLimit` | function | `number` | Tests whether a value is a positive safe integer for a pool record or lease limit. |
|
|
61
61
|
| `isPoolSignal` | function | `AbortSignal` | Tests whether a value is a native `AbortSignal` for the acquire boundary, returning `false` for hostile proxies. |
|
|
62
62
|
|
|
63
63
|
### Types
|
|
64
64
|
|
|
65
65
|
A `Shape` cell holds an interface's data members as bare names in braces, `?` marking an optional member and `plus` introducing its call-signature members, and a type alias's own type literal with a union's arms escaped as `\|`.
|
|
66
66
|
|
|
67
|
-
| API | Kind | Shape
|
|
68
|
-
| ------------------ | --------- |
|
|
69
|
-
| `PoolCode` | type | `'invalid' \| 'destroyed' \| 'create' \| 'cleanup'`
|
|
70
|
-
| `PoolContext` | interface | `{ value?, failures? }`
|
|
71
|
-
| `PoolErrorOptions` | interface | `{ code, cause?, context? }`
|
|
72
|
-
| `PoolEventMap` | type | `{ create, acquire, release, destroy }`
|
|
73
|
-
| `PoolToken` | interface | `{ value } plus release, destroy`
|
|
74
|
-
| `PoolOptions` | interface | `{ on?, error?, create, destroy?, validate?, watch?, max?, min?, restarts? }` | Represents the resource lifecycle options for `Pool` and `createPool`: creation, destruction, validation, capacity, a bounded warm floor, and loss observation. |
|
|
75
|
-
| `PoolInterface` | interface | `{ emitter, size, idle, active } plus start, acquire, clear, destroy`
|
|
67
|
+
| API | Kind | Shape | Summary |
|
|
68
|
+
| ------------------ | --------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| `PoolCode` | type | `'invalid' \| 'destroyed' \| 'create' \| 'cleanup'` | Names the machine-readable failure codes produced by `PoolError`. |
|
|
70
|
+
| `PoolContext` | interface | `{ value?, failures? }` | Represents the structured context attached to a `PoolError`: the rejected input, or the distinct destroy-hook failures an aggregate cleanup collected. |
|
|
71
|
+
| `PoolErrorOptions` | interface | `{ code, cause?, context? }` | Represents the construction options for `PoolError`: the stable code, an optional cause, and optional structured context. |
|
|
72
|
+
| `PoolEventMap` | type | `{ create, acquire, release, destroy }` | Represents the observable resource lifecycle events emitted by a `PoolInterface`. |
|
|
73
|
+
| `PoolToken` | interface | `{ value } plus release, destroy` | Represents a unique lease over one pool-owned resource record, exposing that record as a readonly `value` and ending it through an idempotent `release` or `destroy`. |
|
|
74
|
+
| `PoolOptions` | interface | `{ on?, error?, create, destroy?, validate?, watch?, capacity?, max?, min?, restarts? }` | Represents the resource lifecycle options for `Pool` and `createPool`: creation, destruction, validation, capacity, a bounded warm floor, and loss observation. |
|
|
75
|
+
| `PoolInterface` | interface | `{ emitter, size, idle, active } plus start, acquire, clear, destroy` | Represents a FIFO resource pool with optional bounded capacity, a warm floor, loss recovery, and deterministic teardown, exposing its record counts and a typed lifecycle emitter. |
|
|
76
76
|
|
|
77
77
|
`size` counts every owned record, including records being validated, destroyed, or retained
|
|
78
|
-
after failed cleanup under `min`. `idle` counts
|
|
79
|
-
`active` counts
|
|
80
|
-
|
|
78
|
+
after failed cleanup under `min`. `idle` counts available records with no live lease or pending
|
|
79
|
+
handout. `active` counts records with live leases, counting a shared record once. A partially
|
|
80
|
+
occupied record is active and can accept another lease; it is not idle. A pending handout counts
|
|
81
|
+
against `capacity` but becomes active only at its FIFO grant. An in-flight create reservation
|
|
82
|
+
claims record capacity but is not yet an owned record and therefore is not part of `size`.
|
|
81
83
|
|
|
82
84
|
## Methods
|
|
83
85
|
|
|
@@ -86,21 +88,21 @@ The public call-signature members of `PoolInterface` and `PoolToken`; `Pool` imp
|
|
|
86
88
|
|
|
87
89
|
#### `PoolInterface`
|
|
88
90
|
|
|
89
|
-
| Method | Returns | Summary
|
|
90
|
-
| --------- | ----------------------- |
|
|
91
|
-
| `start` | `Promise<void>` | Fills the warm floor and resets the strikes of a spent floor; without a floor, resolves immediately.
|
|
92
|
-
| `acquire` | `Promise<PoolToken<T>>` | Queues the caller in FIFO order, validates an idle record
|
|
93
|
-
| `clear` | `Promise<void>` | Destroys the records that are idle at this call's synchronous snapshot and restores a started floor.
|
|
94
|
-
| `destroy` | `Promise<void>` | Tears down the pool permanently and returns its stable completion barrier.
|
|
91
|
+
| Method | Returns | Summary |
|
|
92
|
+
| --------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| `start` | `Promise<void>` | Fills the warm floor and resets the strikes of a spent floor; without a floor, resolves immediately. |
|
|
94
|
+
| `acquire` | `Promise<PoolToken<T>>` | Queues the caller in FIFO order, shares an occupied record or validates an idle record, and waits for a floor refill or creates on demand without a floor. |
|
|
95
|
+
| `clear` | `Promise<void>` | Destroys the records that are idle at this call's synchronous snapshot and restores a started floor. |
|
|
96
|
+
| `destroy` | `Promise<void>` | Tears down the pool permanently and returns its stable completion barrier. |
|
|
95
97
|
|
|
96
98
|
#### `PoolToken`
|
|
97
99
|
|
|
98
100
|
The lease returned by `acquire`, with operations that return or dispose its exact record.
|
|
99
101
|
|
|
100
|
-
| Method | Returns | Summary
|
|
101
|
-
| --------- | --------------- |
|
|
102
|
-
| `release` | `void` |
|
|
103
|
-
| `destroy` | `Promise<void>` | Destroys this exact record
|
|
102
|
+
| Method | Returns | Summary |
|
|
103
|
+
| --------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
104
|
+
| `release` | `void` | Ends this exact lease once; a repeat call, and a call after loss or teardown took ownership, are no-ops. Other leases on the record remain live. |
|
|
105
|
+
| `destroy` | `Promise<void>` | Destroys this exact record for every co-holder and invalidates their leases; a repeat call, and a call after release, are no-ops. |
|
|
104
106
|
|
|
105
107
|
## Contract
|
|
106
108
|
|
|
@@ -133,15 +135,16 @@ holder still holds the token. The holder learns of that loss from its own `watch
|
|
|
133
135
|
hook. After disposal, the token's `release()` and `destroy()` calls do nothing. During disposal,
|
|
134
136
|
the first `destroy()` call waits for that cleanup attempt and rejects with `cleanup` if it fails.
|
|
135
137
|
|
|
136
|
-
A failed refill adds a strike. Losing a record
|
|
137
|
-
including failed validation. Granting a lease resets the
|
|
138
|
-
was created after the last strike; successful creation
|
|
139
|
-
|
|
138
|
+
A failed refill adds a strike. Losing a record with no live lease also adds a strike,
|
|
139
|
+
including a previously used record and failed idle validation. Granting a lease resets the
|
|
140
|
+
strikes only when the granted record was created after the last strike; successful creation
|
|
141
|
+
alone does not. Granting an older healthy
|
|
142
|
+
record leaves the strikes unchanged. Any idle record that dies, refills, and dies
|
|
140
143
|
again without a grant between those losses can spend the floor.
|
|
141
144
|
When strikes exceed `restarts`, the floor is spent. With `restarts: 1`, the first failed
|
|
142
145
|
create permits another attempt, and the second refuses the next attempt. `start()` rejects
|
|
143
146
|
with `create` and the last cause; another `start()` resets the strikes. While the floor is
|
|
144
|
-
spent, an acquire without an
|
|
147
|
+
spent, an acquire without an eligible record rejects with `create` after pending refills and
|
|
145
148
|
disposal settle. If the floor retains a record and owns `min` records, that acquire rejects
|
|
146
149
|
with `cleanup` instead, even with live leases. A spent floor and a rejected `start()` still
|
|
147
150
|
serve their live records. A loss without a thrown cause leaves that cause undefined.
|
|
@@ -151,17 +154,22 @@ The credit becomes spendable only when successful disposal removes the record; f
|
|
|
151
154
|
grants no credit. That attempt remains owed during a concurrent refill and never resets the strikes.
|
|
152
155
|
Its failed create adds a strike; its success alone does not reset the strikes. Granting that
|
|
153
156
|
replacement resets the strikes only if no strike occurred after its creation. A record that was leased
|
|
154
|
-
and later
|
|
155
|
-
|
|
157
|
+
and later lost after its last release adds a strike. Under sharing, loss or one lease's
|
|
158
|
+
`destroy()` ends the record for every co-holder, invalidates their leases, and owes one refill
|
|
159
|
+
regardless of the lease count. `token.destroy()` waits for an existing cleanup attempt and
|
|
160
|
+
rejects with `cleanup` if disposal fails.
|
|
156
161
|
A token ends once: after `release()` or `destroy()`, the other call does nothing. Repeating
|
|
157
162
|
either call does nothing. A repeat `token.destroy()` after a `cleanup` rejection resolves
|
|
158
|
-
while the record stays retained.
|
|
163
|
+
while the record stays retained. Refills hold no lease before a caller's grant, so repeated idle
|
|
164
|
+
losses spend the budget. A consumer that keeps a lease without a holder, or repeatedly acquires
|
|
165
|
+
refilled records that fail during use, can keep earning refills and qualifying grant resets.
|
|
166
|
+
The pool cannot distinguish such a lease from useful work; callers must acquire only for a holder.
|
|
159
167
|
|
|
160
168
|
Under `min`, a failed destroy hook leaves its record counted against `max` and excluded from
|
|
161
169
|
idle and active counts. The pool never replaces that retained record or retries its destroy
|
|
162
170
|
hook. The pool can run short; `start()` rejects with `cleanup` if retained records prevent
|
|
163
171
|
filling. An acquire rejects with `cleanup` when the floor retains a record, owns `min` records,
|
|
164
|
-
has nothing
|
|
172
|
+
has nothing eligible, and has no refill or disposal pending, even with live leases. The cause is
|
|
165
173
|
the retained record's own cleanup failure. The terminal `destroy()` barrier
|
|
166
174
|
reports the original cleanup failures. Without `min`, cleanup retains its lazy behavior and
|
|
167
175
|
frees capacity after either hook outcome.
|
|
@@ -189,6 +197,12 @@ await pool.destroy()
|
|
|
189
197
|
|
|
190
198
|
### Capacity and FIFO
|
|
191
199
|
|
|
200
|
+
`capacity` is a positive safe integer limiting simultaneous leases on each record; it defaults
|
|
201
|
+
to 1. `min` and `max` still bound records. Acquisition chooses the eligible record with the
|
|
202
|
+
fewest live leases and reserved handouts. Idle ties follow release order; occupied ties follow
|
|
203
|
+
record creation order. A validating record is unavailable until validation settles.
|
|
204
|
+
Reservations count before any awaited hook.
|
|
205
|
+
|
|
192
206
|
Every `acquire` receives its queue position before a create or validation hook starts. The
|
|
193
207
|
reentrancy-safe pump may assign several hook operations concurrently, but a head commit
|
|
194
208
|
barrier settles successes and failures in request order. A later fast create or validation
|
|
@@ -196,14 +210,16 @@ cannot overtake an earlier slow one. Capacity obeys:
|
|
|
196
210
|
|
|
197
211
|
```text
|
|
198
212
|
owned records + create reservations <= max
|
|
213
|
+
live leases + reserved handouts per record <= capacity
|
|
199
214
|
```
|
|
200
215
|
|
|
201
|
-
`max` must be a positive safe integer. Omit
|
|
216
|
+
`max` must be a positive safe integer. Omit `min` and `max` for an unbounded record count.
|
|
202
217
|
`Infinity`, fractions, zero, negative values, and unsafe integers are invalid.
|
|
203
|
-
Construction snapshots `max` once and validates
|
|
204
|
-
and `error` once each.
|
|
218
|
+
Construction snapshots `max` and `capacity` once and validates them before retention, then
|
|
219
|
+
snapshots `on` and `error` once each.
|
|
205
220
|
|
|
206
|
-
Record
|
|
221
|
+
Record ownership follows these transitions; an occupied record can carry several leases and
|
|
222
|
+
reserved handouts, and returns to available after its last lease and reservation end:
|
|
207
223
|
|
|
208
224
|
```text
|
|
209
225
|
create reservation -> ready -> leased -> available -> validating -> ready
|
|
@@ -212,6 +228,14 @@ create reservation -> ready -> leased -> available -> validating -> ready
|
|
|
212
228
|
floor refill --------------------------> available
|
|
213
229
|
```
|
|
214
230
|
|
|
231
|
+
Validation runs only when reserving an idle record; handouts on an occupied record skip it.
|
|
232
|
+
No caller receives a lease while idle validation is pending. This keeps a failed validation
|
|
233
|
+
from silently disposing a record used by co-holders. After the last lease ends, the next idle
|
|
234
|
+
reuse validates again. A freshly created lazy record keeps its direct handout behavior.
|
|
235
|
+
With `capacity` greater than 1, an occupied record is never revalidated. Only `watch` detects
|
|
236
|
+
its loss: without `watch`, a dead record can keep receiving leases until it becomes idle;
|
|
237
|
+
with `watch`, that exposure lasts until the watch settles.
|
|
238
|
+
|
|
215
239
|
Invalid validation, whether `false` or a thrown value, claims and cleans the record before a
|
|
216
240
|
replacement capacity slot becomes available. Cleanup failure rejects that acquire with
|
|
217
241
|
`PoolError` code `cleanup`; successful cleanup lets the same FIFO waiter seek a replacement.
|
|
@@ -234,10 +258,11 @@ eventual `destroy()` barrier.
|
|
|
234
258
|
|
|
235
259
|
### Release and cleanup
|
|
236
260
|
|
|
237
|
-
A token captures its exact opaque record, so `release()` is correct even when multiple
|
|
238
|
-
records contain the same value. Release is idempotent and
|
|
239
|
-
|
|
240
|
-
|
|
261
|
+
A token captures its exact lease and opaque record, so `release()` is correct even when multiple
|
|
262
|
+
records contain the same value or several tokens share a record. Release is idempotent and
|
|
263
|
+
removes only that lease synchronously. A remaining co-holder keeps the record active, and a
|
|
264
|
+
waiter can share the freed place without validation. After the last release, idle reuse validates.
|
|
265
|
+
A record that remains idle emits `release`. Release after loss or teardown took ownership does nothing.
|
|
241
266
|
The pool disposes a lost lease while its holder still holds the token; the holder learns of
|
|
242
267
|
the loss through its own `watch` or `destroy` hook. After disposal, both token methods do nothing.
|
|
243
268
|
|
|
@@ -318,10 +343,10 @@ const pool = createPool({
|
|
|
318
343
|
Check a candidate value or error against the public boundary guards before acting on it:
|
|
319
344
|
|
|
320
345
|
```ts
|
|
321
|
-
import { PoolError, isPoolError,
|
|
346
|
+
import { PoolError, isPoolError, isPoolLimit, isPoolSignal } from '@orkestrel/pool'
|
|
322
347
|
|
|
323
|
-
|
|
324
|
-
|
|
348
|
+
isPoolLimit(4) // true
|
|
349
|
+
isPoolLimit(Infinity) // false: omit max for unbounded capacity
|
|
325
350
|
isPoolSignal(new AbortController().signal) // true
|
|
326
351
|
|
|
327
352
|
const failure = new PoolError({ code: 'destroyed' })
|