stitchkit 0.102.0 → 0.103.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/dist/agent-runtime/browser-control-contract.d.ts +1118 -0
- package/dist/agent-runtime/browser-control-contract.d.ts.map +1 -0
- package/dist/agent-runtime/browser-controller.d.ts +31 -0
- package/dist/agent-runtime/browser-controller.d.ts.map +1 -0
- package/dist/agent-runtime/harness-control.d.ts.map +1 -1
- package/dist/agent-runtime/harness-realtime.d.ts +25 -0
- package/dist/agent-runtime/harness-realtime.d.ts.map +1 -0
- package/dist/agent-runtime/harness-tools.d.ts +11 -0
- package/dist/agent-runtime/harness-tools.d.ts.map +1 -0
- package/dist/agent-runtime/react.d.ts +4 -0
- package/dist/agent-runtime/react.d.ts.map +1 -0
- package/dist/agent-runtime/run-assertions.d.ts +63 -0
- package/dist/agent-runtime/run-assertions.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-contract.d.ts +46 -7
- package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-frame.d.ts +9 -0
- package/dist/application/diagnostic-journal-frame.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-read-contract.d.ts +110 -0
- package/dist/application/diagnostic-journal-read-contract.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-reader.d.ts +13 -0
- package/dist/application/diagnostic-journal-reader.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-recovery.d.ts +4 -0
- package/dist/application/diagnostic-journal-recovery.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-storage.d.ts +2 -0
- package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/browser.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/browser.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/browser.js +235 -0
- package/dist/entrypoints/agent-runtime/harness-tools.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/harness-tools.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/harness-tools.js +32 -0
- package/dist/entrypoints/agent-runtime/harness.js +11 -226
- package/dist/entrypoints/agent-runtime/react.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/react.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/react.js +8 -0
- package/dist/entrypoints/agent-runtime/realtime.d.ts +2 -0
- package/dist/entrypoints/agent-runtime/realtime.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/realtime.js +159 -0
- package/dist/entrypoints/agent-runtime/testing.d.ts +1 -0
- package/dist/entrypoints/agent-runtime/testing.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/testing.js +67 -2
- package/dist/entrypoints/agent-runtime.js +23 -18
- package/dist/entrypoints/application/diagnostic-journal.d.ts +1 -0
- package/dist/entrypoints/application/diagnostic-journal.d.ts.map +1 -1
- package/dist/entrypoints/application/diagnostic-journal.js +213 -19
- package/dist/entrypoints/application.d.ts +1 -0
- package/dist/entrypoints/application.d.ts.map +1 -1
- package/dist/entrypoints/application.js +10 -2
- package/dist/entrypoints/cli.js +6 -6
- package/dist/entrypoints/index.js +15 -226
- package/dist/entrypoints/node.js +7 -5
- package/dist/entrypoints/observability.js +2 -2
- package/dist/entrypoints/react.js +2 -2
- package/dist/entrypoints/remote.js +3 -3
- package/dist/entrypoints/server.js +10 -8
- package/dist/entrypoints/testing.js +3 -3
- package/dist/entrypoints/tools/invoker.js +5 -5
- package/dist/entrypoints/tools.js +23 -34
- package/dist/entrypoints/tracking.js +2 -2
- package/dist/{index-d82d3xg4.js → index-0c419yx7.js} +1 -1
- package/dist/{index-dvwj1f43.js → index-0efgsyav.js} +1 -1
- package/dist/index-20yvtn9a.js +38 -0
- package/dist/{index-a9pd417t.js → index-5vyd0fkb.js} +1 -34
- package/dist/{index-r1z0rd9c.js → index-7n68nmc6.js} +1 -1
- package/dist/index-860vjkgm.js +48 -0
- package/dist/index-c9d05kvt.js +11 -0
- package/dist/{index-m9fndta6.js → index-ds7jdhep.js} +2 -2
- package/dist/index-jn9g8xdt.js +246 -0
- package/dist/{index-n9tyz8z3.js → index-kgmh97hf.js} +1 -1
- package/dist/{index-c6aagrbd.js → index-kkk1wzsq.js} +3 -3
- package/dist/index-nggfa2yn.js +34 -0
- package/dist/{index-m79yr938.js → index-pw99k9h5.js} +1 -10
- package/dist/index-qapzv4p5.js +54 -0
- package/dist/index-r34mvse1.js +225 -0
- package/dist/index-srs8hj9c.js +10 -0
- package/dist/index-vgkbcnkc.js +29 -0
- package/dist/{index-ewbaywk5.js → index-x1dkwx5x.js} +1 -1
- package/dist/{index-xkhk5d6g.js → index-xgc94hy6.js} +5 -48
- package/dist/{index-3ct7hhq6.js → index-xwq9j1sf.js} +6 -56
- package/dist/{index-hby4qhax.js → index-yex7eg1v.js} +4 -10
- package/dist/{index-1h6gtdrj.js → index-ygkka6zn.js} +1 -1
- package/dist/{index-zs4ms3th.js → index-z3pqcy7r.js} +7 -30
- package/dist/index-z94wht4y.js +156 -0
- package/dist/index-ze1eph1k.js +20 -0
- package/llms/agent-runtime-browser.txt +26 -0
- package/llms/agent-runtime-harness-tools.txt +25 -0
- package/llms/agent-runtime-harness.txt +140 -1
- package/llms/agent-runtime-react.txt +21 -0
- package/llms/agent-runtime-realtime.txt +30 -0
- package/llms/agent-runtime-testing.txt +6 -0
- package/llms/application-diagnostic-journal.txt +2 -0
- package/llms/application.2.txt +157 -267
- package/llms/application.3.txt +278 -0
- package/llms/application.txt +43 -158
- package/llms/stitchkit.txt +9 -5
- package/llms/{upgrading-0.75.0-0.102.0.txt → upgrading-0.75.0-0.103.0.txt} +32 -3
- package/llms/upgrading.txt +1 -1
- package/llms-full.txt +289 -9
- package/llms.txt +11 -7
- package/package.json +13 -1
- package/dist/index-h124epcf.js +0 -103
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# stitchkit/application — stitchkit docs slice, part 3 of 3
|
|
2
|
+
|
|
3
|
+
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
|
+
> `llms.txt` in this package.
|
|
5
|
+
|
|
6
|
+
Parts of this slice:
|
|
7
|
+
- `llms/application.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md)
|
|
8
|
+
- `llms/application.2.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
|
|
9
|
+
- `llms/application.3.txt`: API reference: `stitchkit/application` (docs/api/reference.md)
|
|
10
|
+
|
|
11
|
+
==============================================================================
|
|
12
|
+
# API reference: `stitchkit/application` (docs/api/reference.md)
|
|
13
|
+
==============================================================================
|
|
14
|
+
|
|
15
|
+
## `stitchkit/application`
|
|
16
|
+
|
|
17
|
+
Server-only process-local application composition. See the
|
|
18
|
+
[application kernel guide](../guide/application-kernel.md) and
|
|
19
|
+
[architecture](../architecture/application-kernel.md). Complete consumer
|
|
20
|
+
cutovers are covered by the executable
|
|
21
|
+
[migration recipes](../guide/application-migration-recipes.md).
|
|
22
|
+
|
|
23
|
+
### Kernel and resources
|
|
24
|
+
|
|
25
|
+
| Export | Kind | Summary |
|
|
26
|
+
|--------|------|---------|
|
|
27
|
+
| `createApplication` | function | compose a validated resource DAG into one startup, readiness, admission and shutdown state machine |
|
|
28
|
+
| `StateStore` / `StateStoreUpdate` | _type_ | async atomic read/update boundary shared by durable application state machines |
|
|
29
|
+
| `createProcessLifecycleLedger` / `ProcessLifecycleLedger` / `ProcessLifecycleLedgerConfig` | function / _type_ | durable bounded run history and typed fact subscription |
|
|
30
|
+
| `LifecycleRunSchema` / `LifecycleRun` / `LifecycleStateSchema` / `LifecycleState` / `LifecycleTerminationSchema` / `LifecycleTermination` | schema / _type_ | versioned process-run state — open (`active`, `draining` with `unavailableAt`) and ended (`clean`, `forced`, `startup-failed`, `hot-reload`, `abnormal`) |
|
|
31
|
+
| `PreviousExitSchema` / `PreviousExit` / `StartFact` / `ReadyFact` / `DrainingFact` / `ShutdownFact` / `ProcessLifecycleFact` | schema / _type_ | first-boot, hot-reload, clean, forced, startup-failed, handoff and abnormal lifecycle facts; `processGapMs` on start, `downtimeMs` (unavailable → ready) on ready |
|
|
32
|
+
| `transitionProcessStart` / `transitionProcessReady` / `transitionProcessDraining` / `transitionProcessShutdown` | function | pure idempotent runId+pid-owned transitions |
|
|
33
|
+
| `LifecycleTransition` / `TransitionStartInput` / `TransitionRunInput` / `TransitionShutdownInput` / `SameVersionOverlap` / `VersionChangeOverlap` | _type_ | pure transition inputs (`TransitionRunInput` for ready and draining, extended with `forced` for shutdown), the same-build overlap policy (`abnormal` default / `handoff`), the version-change overlap policy (`handoff` default / `abnormal`) and state+fact result |
|
|
34
|
+
| `lifecycleLedgerResource` / `LifecycleLedgerResource` / `LifecycleLedgerResourceConfig` | function / _type_ | managed-resource adapter that records start, readiness, admission stop (draining) and shutdown |
|
|
35
|
+
| `createNotificationOutbox` / `NotificationOutbox` / `NotificationOutboxConfig` | function / _type_ | bounded at-least-once queue with durable claims, leases, retries and supersede |
|
|
36
|
+
| `NotificationOutboxItem` / `NotificationOutboxReceipt` / `NotificationOutboxState` / `NotificationSend` / `NotificationFailureClassification` / `DroppedNotification` / `EnqueueNotification` | _type_ | versioned queue records, stable send identity and delivery decisions |
|
|
37
|
+
| `notificationOutboxStateSchema` | function | strict persisted-state schema over an application payload schema |
|
|
38
|
+
| `notificationOutboxResource` / `NotificationOutboxResource` / `NotificationOutboxResourceConfig` | function / _type_ | thin managed-resource scheduler over an outbox handle |
|
|
39
|
+
| `createDirectoryInbox` (from `stitchkit/application/directory-inbox`) / `DirectoryInbox` / `DirectoryInboxConfig` / `DirectoryInboxDelivery` / `DirectoryInboxResource` | function / _type_ | managed resource delivering each `<name>.json` entry another program drops into a directory to the application at least once, after readiness; separate durable taken/done records, leases, bounded retry |
|
|
40
|
+
| `DirectoryInboxStateSchema` / `DirectoryInboxState` / `DirectoryInboxRejection` / `DirectoryInboxRejectionReasonSchema` / `DirectoryInboxRejectionReason` | schema / _type_ | the inbox's claims, receipts and rejections (`invalid`, `too-large`, `attempt-limit`) |
|
|
41
|
+
| `ApplicationHandle.restart` | method | replace one resource and everything that depends on it, leaving the rest of the graph running and the process epoch unchanged |
|
|
42
|
+
| `ApplicationRestartInputSchema` / `ApplicationRestartInput` | schema / _type_ | the resource to replace, by id, and optionally `gracePeriodMs` / `forceTimeoutMs` for this restart — the application's own shutdown budget otherwise |
|
|
43
|
+
| `ApplicationRestartResultSchema` / `ApplicationRestartResult` | schema / _type_ | the subtree that was actually taken down and brought back, in start order, with the outcome, the reason on anything but success, and how long it took |
|
|
44
|
+
| `ApplicationRestartOutcomeSchema` / `ApplicationRestartOutcome` | schema / _type_ | `restarted`, `failed` or `refused` — a refusal (unknown id, shutting down, not yet ready) is not a failure and touches nothing |
|
|
45
|
+
| `ApplicationResourceFailure` | _type_ | one resource failure with the cause its phase label cannot carry — delivered to `onResourceFailure` |
|
|
46
|
+
| `ApplicationResourcePhase` | _type_ | the phase a managed resource failed in — the vocabulary of `ApplicationResourceShutdown.failures` |
|
|
47
|
+
| `ApplicationShutdownOptionsSchema` / `ApplicationShutdownOptions` | schema / _type_ | the two shutdown budgets and an abort signal — without the HTTP-only `retryAfterSeconds` |
|
|
48
|
+
| `ApplicationShutdownBudgetSchema` / `ApplicationShutdownBudget` | schema / _type_ | the same two budgets without a signal — `ApplicationConfig.shutdown`, the default for `shutdown()` and the only budget a failed startup's rollback can read |
|
|
49
|
+
| `ActivityTokenBrand` | const | the brand symbol `ActivityToken` carries, exported so `ActivityProjection` is implementable |
|
|
50
|
+
| `defineManagedResource` | function | retain the exact typed resource declaration; every invoked start is rollback-eligible |
|
|
51
|
+
| `managedServerResource` | function | own a managed server's lifecycle without copying its HTTP/WebSocket shutdown machine — a thunk is called during `start`, and the handle is published to dependants |
|
|
52
|
+
| `managedResourceDependencyId` | function | the id of a dependency declared either as a string or as the resource itself |
|
|
53
|
+
| `createApplicationHealthHandler` | function | build a Fetch-clean liveness or readiness response from the sanitized application snapshot |
|
|
54
|
+
| `createApplicationOperationalHandlers` | function | compose always-readable status plus the canonical readiness/liveness handlers |
|
|
55
|
+
| `ApplicationAdmissionError` | class | stable `APPLICATION_NOT_ACCEPTING` rejection from `admission.run(...)` |
|
|
56
|
+
| `ApplicationConfig` / `ApplicationHandle` | _type_ | application declaration and its start/snapshot/subscription/admission/shutdown handle |
|
|
57
|
+
| `ApplicationAdmission` / `ApplicationOperationLease` | _type_ | atomic process-local admission and idempotent release primitive |
|
|
58
|
+
| `ManagedResource` / `ManagedResourceContext` / `ManagedResourceStartResult` | _type_ | resource lifecycle callbacks, shared deadlines, health reporting, separate readiness/completion promises and the value a resource publishes to its dependants |
|
|
59
|
+
| `ManagedResourceAdmission` | _type_ | `context.admission`: `acquire()` now or `null`, and `acquireWhenAccepting(signal)` for a resource that fetches work — a poller waits instead of fetching while the application is starting or degraded; rejects on abort and once the application can no longer admit |
|
|
60
|
+
| `ManagedResourceDependency` | _type_ | a dependency named by id or given as the resource itself — the second form is what `context.use(...)` can type |
|
|
61
|
+
| `ManagedResourcePublished` | _type_ | the value type `context.use(resource)` returns, recovered from that resource's own `start` |
|
|
62
|
+
| `ManagedResourcePublishesNoValue` | _type_ | what `context.use(...)` returns for a resource that publishes nothing — a branded refusal rather than `never`, so reading it does not silently compile |
|
|
63
|
+
| `ManagedServerResourceConfig` | _type_ | the server or a sync/async factory receiving `ManagedResourceContext`, plus stable ID, dependencies and server shutdown policy (`retryAfterSeconds`, `realtimeCloseTimeoutMs`) |
|
|
64
|
+
| `ManagedServerResource` | _type_ | the resource `managedServerResource` returns, whose `start` publishes the `ManagedServerHandle` |
|
|
65
|
+
| `ApplicationHealthHandlerOptions` / `ApplicationHealthHandlerOptionsSchema` | _type_ / schema | liveness/readiness selection and sanitized `Retry-After` policy |
|
|
66
|
+
| `ApplicationOperationalHandlers` / `ApplicationOperationalHandlersOptions` / `ApplicationOperationalHandlersOptionsSchema` | _type_ / schema | conventional status/readiness/liveness route surface and shared retry policy |
|
|
67
|
+
|
|
68
|
+
### Bounded admission
|
|
69
|
+
|
|
70
|
+
| Export | Kind | Summary |
|
|
71
|
+
|--------|------|---------|
|
|
72
|
+
| `createBoundedAdmission` | function | process-local no-queue global/per-key concurrency and rate leases, optionally composed with application admission |
|
|
73
|
+
| `BoundedAdmissionPolicySchema` / `BoundedAdmissionPolicy` | schema / _type_ | finite global budget and optional finite per-key budget with `maxKeys`, declared either as one flat ceiling or as a resolver — never both |
|
|
74
|
+
| `BoundedAdmissionPerKeyLimitsSchema` / `BoundedAdmissionPerKeyLimits` | schema / _type_ | one key's resolved ceiling: `maxConcurrent` and optional `rate` |
|
|
75
|
+
| `BoundedAdmissionPerKeyLimitResolver` | _type_ | `(key) => limits`, resolved on a key's first admission and cached until the key is evicted |
|
|
76
|
+
| `BoundedRateBudgetSchema` / `BoundedRateBudget` | schema / _type_ | `{ limit, intervalMs }` monotonic sliding-window budget |
|
|
77
|
+
| `BoundedAdmissionStateSchema` / `BoundedAdmissionState` | schema / _type_ | `accepting \| draining \| closed` |
|
|
78
|
+
| `BoundedAdmissionRefusalReasonSchema` / `BoundedAdmissionRefusalReason` | schema / _type_ | exact local/upstream refusal vocabulary |
|
|
79
|
+
| `BoundedAdmissionSnapshotSchema` / `BoundedAdmissionSnapshot` | schema / _type_ | absolute active/lifetime/refusal/rate-accounting counters |
|
|
80
|
+
| `BoundedAdmission` / `BoundedAdmissionConfig` / `BoundedAdmissionClock` | _type_ | handle, policy/upstream/clock configuration and monotonic clock seam |
|
|
81
|
+
| `BoundedAdmissionResult` / `BoundedAdmissionLeaseResult` / `BoundedAdmissionRefusedResult` | _type_ | explicit leased-or-refused acquisition result; retry time exists only for rate bounds |
|
|
82
|
+
| `BoundedOperationLease` | _type_ | idempotent release lease, optionally carrying its key |
|
|
83
|
+
| `BoundedOperationRunContext` / `BoundedOperationRunOptions` | _type_ | underlying work signal and caller abort/timeout wait budget |
|
|
84
|
+
| `BoundedAdmissionDrainOptions` / `BoundedAdmissionDrainResult` / `BoundedAdmissionForceResult` | _type_ | bounded drain inputs and honest remaining-work results |
|
|
85
|
+
| `BoundedAdmissionRefusalError` | class | `run()` refusal with reason and optional `retryAfterMs` |
|
|
86
|
+
| `BoundedOperationWaitError` | class | caller wait ended as `cancelled` or `timed-out`; underlying capacity remains leased until work settles |
|
|
87
|
+
|
|
88
|
+
### Revision wake-up
|
|
89
|
+
|
|
90
|
+
| Export | Kind | Summary |
|
|
91
|
+
|--------|------|---------|
|
|
92
|
+
| `createRevisionSignal` | function | finite broadcast wait for the next monotonic process-local revision |
|
|
93
|
+
| `RevisionSignal` / `RevisionSignalConfig` / `RevisionSignalClock` / `RevisionSignalTimer` | _type_ | signal handle, waiter bound and replaceable timer boundary |
|
|
94
|
+
| `RevisionSignalWaitOptions` | _type_ | optional caller `signal` and positive `timeoutMs`; absent options wait until advance or close |
|
|
95
|
+
| `RevisionSignalWaitOutcomeSchema` / `RevisionSignalWaitOutcome` | schema / _type_ | `changed \| timed-out \| aborted \| closed \| capacity` |
|
|
96
|
+
| `RevisionSignalWaitResultSchema` / `RevisionSignalWaitResult` | schema / _type_ | terminal wait outcome with the revision observed at settlement |
|
|
97
|
+
| `RevisionSignalAdvanceResultSchema` / `RevisionSignalAdvanceResult` | schema / _type_ | successful `advanced` or post-close `closed`, with the resulting revision |
|
|
98
|
+
| `RevisionSignalStateSchema` / `RevisionSignalState` | schema / _type_ | `open \| closed` lifecycle |
|
|
99
|
+
| `RevisionSignalSnapshotSchema` / `RevisionSignalSnapshot` | schema / _type_ | current revision, finite pending count and lifetime outcome counters |
|
|
100
|
+
|
|
101
|
+
### Bounded delivery
|
|
102
|
+
|
|
103
|
+
| Export | Kind | Summary |
|
|
104
|
+
|--------|------|---------|
|
|
105
|
+
| `createBoundedChannel` | function | finite single-reader async channel with explicit ordered or latest-value policy |
|
|
106
|
+
| `BoundedChannelPolicySchema` / `BoundedChannelPolicy` | schema / _type_ | `ordered \| latest` retention policy |
|
|
107
|
+
| `BoundedChannelStateSchema` / `BoundedChannelState` | schema / _type_ | `open \| draining \| closed \| failed` |
|
|
108
|
+
| `BoundedChannelSnapshotSchema` / `BoundedChannelSnapshot` | schema / _type_ | exact retained count/bytes, waiter and outcome counters |
|
|
109
|
+
| `BoundedChannel` / `BoundedChannelConfig` / `BoundedChannelCloseOptions` | _type_ | iterator/offer handle, explicit count/byte/size policy and drain/discard close mode |
|
|
110
|
+
| `BoundedChannelOfferResult` | _type_ | `delivered`, `queued`, `coalesced`, or reasoned `refused` outcome |
|
|
111
|
+
| `BoundedChannelReaderError` | class | refusal of a second concurrent pending `next()` |
|
|
112
|
+
| `createCreditWindow` | function | finite byte-credit lease window with exact once-only replenishment |
|
|
113
|
+
| `CreditWindow` / `CreditWindowSnapshot` / `CreditWindowSnapshotSchema` | _type_ / schema | byte-credit handle and absolute accounting record |
|
|
114
|
+
| `CreditAcquireResult` / `CreditLease` | _type_ | reasoned refusal or idempotently releasable byte-credit lease |
|
|
115
|
+
| `CreditAcquireWaitOptions` | _type_ | `signal` / `timeoutMs` for the waiting `acquire` overload; absent budget waits until credit, close or abort |
|
|
116
|
+
| `CreditWaitResult` / `CreditWaitRefusalReason` | _type_ | waiting-acquire outcome; `insufficient-credit` is absent by construction, `timed-out` and `aborted` replace it |
|
|
117
|
+
|
|
118
|
+
### Bounded diagnostic journal
|
|
119
|
+
|
|
120
|
+
| Export | Kind | Summary |
|
|
121
|
+
|--------|------|---------|
|
|
122
|
+
| `createDiagnosticJournal` | function | create one schema-owned FIFO JSONL writer with bounded retained memory, exclusive local path ownership and finite rotation |
|
|
123
|
+
| `DiagnosticJournalConfig` / `DiagnosticJournal` | _type_ | owner schema/path/limits/failure observer and the synchronous `submit`, bounded-wait `flush`/`close`, status handle |
|
|
124
|
+
| `DiagnosticJournalLimitsSchema` / `DiagnosticJournalLimits` | schema / _type_ | positive event, pending-item, pending-byte, file-byte and retained-file limits |
|
|
125
|
+
| `DiagnosticJournalLockPolicySchema` / `DiagnosticJournalLockPolicy` | schema / _type_ | `refuse` (default) or `reclaim-stale`, which reclaims only a lock whose recorded owner is provably gone |
|
|
126
|
+
| `readDiagnosticJournalLockDiagnosis` / `DiagnosticJournalLockDiagnosis` | function / _type_ | why a `reclaim-stale` acquisition refused — attribution, PID liveness and optional process `identity` evidence (`matched`, `different-boot`, `reused-pid`, `pid-gone`, `legacy`, `unavailable`) — read off the thrown `EEXIST` |
|
|
127
|
+
| `DiagnosticJournalSubmitResultSchema` / `DiagnosticJournalSubmitResult` | schema / _type_ | accepted epoch/sequence or explicit invalid, oversized, capacity, closed or failed refusal |
|
|
128
|
+
| `DiagnosticJournalStatusSchema` / `DiagnosticJournalStatus` | schema / _type_ | state, limits, exact admission/write/failure counters, pending ownership, rotations, partial tails and last safe sequences |
|
|
129
|
+
| `DiagnosticJournalFrameSchema` / `DiagnosticJournalFrame` | schema / _type_ | version-1 JSONL frame carrying process epoch, contiguous accepted sequence and schema-validated JSON event |
|
|
130
|
+
| `DiagnosticJournalWaitResultSchema` / `DiagnosticJournalWaitResult` | schema / _type_ | flush settlement boundary with truthful settled, timed-out or cancelled result |
|
|
131
|
+
| `DiagnosticJournalCloseResultSchema` / `DiagnosticJournalCloseResult` | schema / _type_ | physical close or caller timeout/cancellation without pretending an active write stopped |
|
|
132
|
+
| `DiagnosticJournalStateSchema` / `DiagnosticJournalState` | schema / _type_ | `open \| draining \| closed \| failed` |
|
|
133
|
+
| `DiagnosticJournalRefusalReasonSchema` / `DiagnosticJournalRefusalReason` | schema / _type_ | `closed \| failed \| invalid \| oversized \| item-capacity \| byte-capacity` |
|
|
134
|
+
| `DiagnosticJournalFailurePhaseSchema` / `DiagnosticJournalFailurePhase` | schema / _type_ | internal `write \| rotation \| close` failure phase exposed only to status and the isolated observer |
|
|
135
|
+
| `DiagnosticJournalWaitOptions` / `DiagnosticJournalFailure` | _type_ | caller wait signal/timeout and isolated internal failure callback record |
|
|
136
|
+
| `DiagnosticJournalAnomalySchema` / `DiagnosticJournalAnomaly` | schema / _type_ | corrupt-row reason, file, zero-based byte offset, one-based line, tail/interior position and skipped bytes |
|
|
137
|
+
| `createDiagnosticJournalReadResultSchema` / `DiagnosticJournalReadResult` | function / _type_ | owner-schema frame output or explicit anomaly; retains transformed event output types |
|
|
138
|
+
| `DiagnosticJournalRecoveryStatusSchema` / `DiagnosticJournalRecoveryStatus` | schema / _type_ | bounded startup inspection counts and first/last anomaly locations |
|
|
139
|
+
| `DiagnosticJournalRecoveryError` | class | torn single-file startup refusal carrying recovery observations, preserving evidence and releasing its lock |
|
|
140
|
+
|
|
141
|
+
`accepted` is bounded in-memory admission and `written` is completed append, not `fsync` or durable
|
|
142
|
+
delivery. Its filesystem reader is in the diagnostic-journal leaf; there is no managed replay/upload API. See the
|
|
143
|
+
[guide](../guide/application-kernel.md#bounded-local-diagnostic-journal),
|
|
144
|
+
[architecture](../architecture/diagnostic-journal.md) and [ADR
|
|
145
|
+
0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
|
|
146
|
+
|
|
147
|
+
### Managed schedules
|
|
148
|
+
|
|
149
|
+
| Export | Kind | Summary |
|
|
150
|
+
|--------|------|---------|
|
|
151
|
+
| `createManagedSchedule` | function | fixed-rate process-local timer that activates after top-level readiness and participates in drain |
|
|
152
|
+
| `ManagedScheduleOverlapSchema` / `ManagedScheduleOverlap` | schema / _type_ | `skip`, `queue-one` or bounded `parallel` overlap policy |
|
|
153
|
+
| `ManagedScheduleErrorPolicySchema` / `ManagedScheduleErrorPolicy` | schema / _type_ | `continue` or `stop-schedule` after an observed callback failure |
|
|
154
|
+
| `ManagedScheduleDescriptorSchema` / `ManagedScheduleDescriptor` | schema / _type_ | immutable public schedule identity and cadence policy |
|
|
155
|
+
| `ManagedScheduleStatusSchema` / `ManagedScheduleStatus` | schema / _type_ | absolute schedule state, revision, counters and timestamps |
|
|
156
|
+
|
|
157
|
+
Schedule authoring additionally exports `ManagedSchedule`, `ManagedScheduleConfig`,
|
|
158
|
+
`ManagedScheduleRunContext`, `ManagedScheduleClock` and `ManagedScheduleTimer`.
|
|
159
|
+
The clock exposes monotonic cadence/deadline arithmetic and a wall-clock projection for portable
|
|
160
|
+
status timestamps; it is a deterministic test boundary, not a durable scheduler.
|
|
161
|
+
|
|
162
|
+
### Application and activity projection
|
|
163
|
+
|
|
164
|
+
| Export | Kind | Summary |
|
|
165
|
+
|--------|------|---------|
|
|
166
|
+
| `createActivityProjection` | function | aggregate anonymous process-local activity into declared bounded stages and absolute snapshots |
|
|
167
|
+
| `createApplicationSnapshotSink` | function | latest-value delivery with one write in flight and one replaceable pending revision |
|
|
168
|
+
| `applicationLifecycleEvent` | function | project a sanitized lifecycle fact from a canonical application snapshot |
|
|
169
|
+
| `createApplicationEventSink` | function | bounded failure-isolated lifecycle-event delivery; events are not canonical state |
|
|
170
|
+
| `ActivitySnapshotSchema` / `ActivitySnapshot` | schema / _type_ | epoch, monotonic revision, timestamps, declared stages and aggregate counts |
|
|
171
|
+
| `ApplicationSnapshotSinkStatusSchema` / `ApplicationSnapshotSinkStatus` | schema / _type_ | immutable latest-value sink delivery and coalescing counters |
|
|
172
|
+
| `ApplicationLifecycleEventSchema` / `ApplicationLifecycleEvent` | schema / _type_ | sanitized operator-facing application lifecycle fact |
|
|
173
|
+
|
|
174
|
+
Activity authoring additionally exports `ActivityId`, `ActivityIdSchema`,
|
|
175
|
+
`ActivityStageId`, `ActivityStageIdSchema`, `ActivityStageSnapshot`,
|
|
176
|
+
`ActivityStageSnapshotSchema`, `ActivityLiveState`, `ActivityLiveStateSchema`,
|
|
177
|
+
`ActivityProjection`, `ActivityProjectionConfig`,
|
|
178
|
+
`ActivityProjectionSubscriberError`, `ActivityToken` and `ActivityTransition`.
|
|
179
|
+
Latest-value delivery exports `ApplicationSnapshotSink`,
|
|
180
|
+
`ApplicationSnapshotSinkConfig`, `ApplicationSnapshotSinkError` and
|
|
181
|
+
`RevisionedApplicationSnapshot`; event delivery exports `ApplicationEventSink`
|
|
182
|
+
and `ApplicationEventSinkConfig`.
|
|
183
|
+
|
|
184
|
+
### Canonical application records
|
|
185
|
+
|
|
186
|
+
These are also published on their own as
|
|
187
|
+
[`stitchkit/application/schemas`](#stitchkitapplicationschemas), which carries
|
|
188
|
+
no server runtime and can therefore be imported from a browser bundle.
|
|
189
|
+
|
|
190
|
+
The entrypoint exports each Zod schema beside its inferred type:
|
|
191
|
+
`ApplicationIdSchema` / `ApplicationId`, `ApplicationLifecycleSchema` /
|
|
192
|
+
`ApplicationLifecycle`, `ApplicationHealthSchema` / `ApplicationHealth`,
|
|
193
|
+
`ManagedResourceStateSchema` / `ManagedResourceState`,
|
|
194
|
+
`ApplicationAdmissionSnapshotSchema` / `ApplicationAdmissionSnapshot`,
|
|
195
|
+
`ManagedResourceSnapshotSchema` / `ManagedResourceSnapshot`,
|
|
196
|
+
`ApplicationSnapshotSchema` / `ApplicationSnapshot`,
|
|
197
|
+
`ApplicationStatusProjectionSchema` / `ApplicationStatusProjection` with
|
|
198
|
+
`projectApplicationStatus` — what a status or probe endpoint may publish, and
|
|
199
|
+
the function that derives it from a snapshot,
|
|
200
|
+
`ApplicationResourceShutdownSchema` / `ApplicationResourceShutdown`, and
|
|
201
|
+
`ApplicationShutdownResultSchema` / `ApplicationShutdownResult`.
|
|
202
|
+
|
|
203
|
+
### Decisions
|
|
204
|
+
|
|
205
|
+
A pipeline of policies that each vote `allow`, `deny` or `defer`, sharing its
|
|
206
|
+
vocabulary with an event topic declared `mode: 'decision'`.
|
|
207
|
+
|
|
208
|
+
| Export | Kind | Summary |
|
|
209
|
+
|--------|------|---------|
|
|
210
|
+
| `createDecisionPipeline` | function | run policies in declaration order; the first terminal verdict wins and the rest do not run |
|
|
211
|
+
| `DecisionPipelineConfig` | _type_ | `policyTimeoutMs` — how long one policy has to answer. Required, no default: a policy that never settles hangs every caller of the operation it guards |
|
|
212
|
+
| `PolicyDecisionSchema` / `PolicyDecision` | schema / _type_ | `allow`, `deny` with a reason, or `defer` — a deny cannot be silent |
|
|
213
|
+
| `DecisionPolicy` / `DecisionPipeline` | _types_ | one named voter over the caller's subject, and the pipeline it composes into |
|
|
214
|
+
| `DecisionResult` / `DecisionTraceEntry` | _types_ | the verdict, and the trace of what actually ran — not what was declared |
|
|
215
|
+
| `DecisionUndecidedError` | class | every policy deferred and no undecided outcome was declared: an unanswered question, raised rather than guessed |
|
|
216
|
+
| `DecisionPolicyError` | class | a policy returned a non-decision, threw, or ran past `policyTimeoutMs` — one error for all three, carrying the policy id and the trace so far |
|
|
217
|
+
|
|
218
|
+
### Keyspace and watched reads
|
|
219
|
+
|
|
220
|
+
| Export | Kind | Summary |
|
|
221
|
+
|--------|------|---------|
|
|
222
|
+
| `defineKeyspace` / `keyspaceResource` | function | a named record set read synchronously from memory and written through one serialised chain; backend first, then memory, then the change event |
|
|
223
|
+
| `openKeyspace` / `OpenedKeyspace` | function / type | the same keyspace opened directly, for an application that owns its own lifecycle rather than declaring resources to a kernel |
|
|
224
|
+
| `KeyspaceBackend` / `KeyspaceDeclaration` / `KeyspaceChange` / `KeyspaceResourceConfig` / `OpenKeyspace` | _types_ | the four-method durability port, the declaration, the announced change, the resource's options and the published handle. `backend` takes a value or a **factory** — a factory is called once per generation, so a restarted keyspace gets a backend that was never closed |
|
|
225
|
+
| `memoryKeyspaceBackend` / `sqliteKeyspaceBackend` / `SqliteKeyspaceBackendConfig` | function / type | a disposable in-process backend, and one table with a key and a JSON payload over a caller-owned database |
|
|
226
|
+
| `SqliteDatabase` / `SqliteStatement` / `SqliteValue` | _types_ | the minimal synchronous SQLite boundary the framework types against |
|
|
227
|
+
| `createWatchHub` / `watchKey` | function | one read per question however many are asking: single-flight per key, re-read on a declared topic, publish only what changed |
|
|
228
|
+
| `WatchHub` / `WatchHubConfig` / `WatchOperation` / `WatchSubscriber` / `AttachedWatcher` | _types_ | the hub, its read/watchable/invalidation policy, the operation identity, and one connection's attachment |
|
|
229
|
+
|
|
230
|
+
→ [ADR 0152](../decisions/0152-a-keyspace-is-memory-that-nothing-reaches-before-it-is-durable.md),
|
|
231
|
+
[ADR 0153](../decisions/0153-a-watched-read-is-one-read-per-question.md).
|
|
232
|
+
|
|
233
|
+
### Managed change subscriptions and scoped watches
|
|
234
|
+
|
|
235
|
+
`changeSubscriptionResource` (`stitchkit/application`) accepts
|
|
236
|
+
`ChangeSubscriptionConfig`: `id`, unique `keys` (1–128, at most 256 characters each),
|
|
237
|
+
`connect(signal)`, `reconcile(key, context)`, required `reconcileIntervalMs` (10 ms–1 h),
|
|
238
|
+
optional `timeoutMs` (30000; 1 ms–1 h), `backoff`, and `onError`.
|
|
239
|
+
`ChangeConnection` supplies `subscribe({ signal, hint, disconnected })`, which completes subscription
|
|
240
|
+
before the first read; `close()` releases it. `ChangeReconciliation` exposes `signal`
|
|
241
|
+
and a synchronous `commit(callback)` guard against late publication. Drivers must
|
|
242
|
+
honor cancellation. Uncooperative work retains its slot until settled instead of
|
|
243
|
+
allowing overlapping connections/reads. Errors reach `onError`; no raw payload or
|
|
244
|
+
connection string is logged by this resource. Recovery runs after reconnect and
|
|
245
|
+
periodically even when no notification arrives.
|
|
246
|
+
|
|
247
|
+
`WatchHubConfig` adds `maxSources` (1024), `maxSubscribers` (1024), and optional
|
|
248
|
+
`reconcileIntervalMs` (10 ms–1 h). `hub.attach(subscriber, scope?)` accepts a
|
|
249
|
+
`WatchAdmissionScope` containing a **server-verified** `key` (1–512 characters) and
|
|
250
|
+
revocation `signal`. The key separates sharing and is the optional third argument
|
|
251
|
+
of `read(operation, args, scope)`; a key's `instance` routes frames and never
|
|
252
|
+
separates sources. Attached over `maxSubscribers`, a subscriber gets a watcher whose
|
|
253
|
+
`open` refuses with `Watch subscriber capacity exceeded`; `attach` does not throw
|
|
254
|
+
for capacity. It must represent account, session and permissions;
|
|
255
|
+
never trust a client-supplied owner ID as that scope.
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
### Notification action and projection receipts
|
|
260
|
+
|
|
261
|
+
`NotificationOutboxConfig.delivery` accepts `NotificationDeliveryConfig`:
|
|
262
|
+
immutable executor `version`, pure `actions(payload)` plan selector (1–128 unique
|
|
263
|
+
names, each at most 128 characters), and idempotent `project(notification, receipts)`.
|
|
264
|
+
`send` receives optional `action` and stable `idempotencyKey`, and returns a JSON
|
|
265
|
+
remote receipt (void becomes null). A result that is not JSON or does not fit the
|
|
266
|
+
byte budget is kept as `receipt: null` with `unrecorded: 'not-json' | 'too-large'`;
|
|
267
|
+
the action stays confirmed and is not sent again. `retiredVersions` maps earlier
|
|
268
|
+
plan versions to their `NotificationProjection` so queued items drain after an
|
|
269
|
+
executor upgrade; an unknown version is reported to `onError` as
|
|
270
|
+
`NotificationPlanVersionError` and waits, spending no attempt and not consulting
|
|
271
|
+
`classify`, for an executor that knows it. `NotificationDeliveryStateSchema` validates the
|
|
272
|
+
optional `NotificationDeliveryState` on queued items and completed receipts:
|
|
273
|
+
`version`, `actions`, `receipts` and optional `projectedAt`. Checkpoints share the
|
|
274
|
+
existing atomic StateStore and lease fence. Receipt retention and serialized byte
|
|
275
|
+
budgets still apply. Single-send configuration remains valid without `delivery`.
|
|
276
|
+
A remote result lost before its checkpoint may be sent again; provider idempotency
|
|
277
|
+
or reconciliation is required. A projection may repeat after a crash before its
|
|
278
|
+
checkpoint. Business-transaction enqueue and durable quarantine are not implied.
|
package/llms/application.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# stitchkit/application — stitchkit docs slice, part 1 of
|
|
1
|
+
# stitchkit/application — stitchkit docs slice, part 1 of 3
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
Parts of this slice:
|
|
8
8
|
- `llms/application.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md)
|
|
9
|
-
- `llms/application.2.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
|
|
9
|
+
- `llms/application.2.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
|
|
10
|
+
- `llms/application.3.txt`: API reference: `stitchkit/application` (docs/api/reference.md)
|
|
10
11
|
|
|
11
12
|
==============================================================================
|
|
12
13
|
# Guide: Managed application kernel (docs/guide/application-kernel.md)
|
|
@@ -18,7 +19,7 @@ description: Compose process-local resources, schedules, readiness, drain and op
|
|
|
18
19
|
type: architecture
|
|
19
20
|
status: active
|
|
20
21
|
created: 2026-08-23
|
|
21
|
-
updated: 2026-09-
|
|
22
|
+
updated: 2026-09-30 17:41 +07:00
|
|
22
23
|
---
|
|
23
24
|
|
|
24
25
|
# Managed application kernel
|
|
@@ -665,10 +666,47 @@ short-lived reclaim guard.
|
|
|
665
666
|
|
|
666
667
|
`flush()` means every accepted append through that call's boundary settled. It is not `fsync`, a
|
|
667
668
|
durable receipt, exactly-once execution or remote delivery. Timeout/cancellation bound only the
|
|
668
|
-
waiter; the writer retains physical capacity until settlement. There is no
|
|
669
|
-
Use a durable application store or deployment-owned log collector when restart recovery, replay or
|
|
669
|
+
waiter; the writer retains physical capacity until settlement. There is no upload or managed replay API.
|
|
670
|
+
Use a durable application store or deployment-owned log collector when durable restart recovery, replay or
|
|
670
671
|
aggregation is required. → [ADR 0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
|
|
671
672
|
|
|
673
|
+
For finite inspection, use the shared reader with an explicit oldest-to-newest list of existing
|
|
674
|
+
files. Keep anomaly reporting outside the journal being inspected:
|
|
675
|
+
|
|
676
|
+
```ts
|
|
677
|
+
import { readDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
|
|
678
|
+
import { z } from 'zod'
|
|
679
|
+
|
|
680
|
+
const eventSchema = z.object({
|
|
681
|
+
kind: z.enum(['resource_failed', 'recovery_started']),
|
|
682
|
+
resource: z.string().max(80),
|
|
683
|
+
}).strict()
|
|
684
|
+
|
|
685
|
+
for await (const row of readDiagnosticJournal({
|
|
686
|
+
paths: ['/var/lib/example/diagnostic.jsonl.1', '/var/lib/example/diagnostic.jsonl'],
|
|
687
|
+
eventSchema,
|
|
688
|
+
maxLineBytes: 4 * 1024,
|
|
689
|
+
})) {
|
|
690
|
+
if (row.type === 'anomaly') internalLogger.warn(row.anomaly)
|
|
691
|
+
else inspectEvent(row.frame.event)
|
|
692
|
+
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
The reader bounds memory by line size plus a fixed chunk, skips oversized/damaged rows with
|
|
696
|
+
explicit anomalies, and still returns valid rows before and after them. `offset` is zero-based
|
|
697
|
+
bytes; `line` is one-based. `position` distinguishes the file's tail from interior damage.
|
|
698
|
+
A valid frame lacking its final LF yields a warning with `skippedBytes: 0` and its frame.
|
|
699
|
+
Each file's size is captured at open; concurrent appends are excluded. Missing files, permissions,
|
|
700
|
+
symlinks, non-regular files and mid-read truncation throw rather than masquerading as bad data.
|
|
701
|
+
The caller owns file selection and coordination with an active rotator.
|
|
702
|
+
|
|
703
|
+
Writer startup inspects retained and active files under its lock. On damage,
|
|
704
|
+
`journal.getStatus().recovery` contains counts and first/last anomaly locations, reconstructed
|
|
705
|
+
again on restart from the preserved bytes. This describes startup observations, not live
|
|
706
|
+
continuous inspection. `maxFiles: 1` cannot preserve a torn active file by rotation and throws
|
|
707
|
+
`DiagnosticJournalRecoveryError` before removing any evidence; configure at least two slots.
|
|
708
|
+
Normal rotation retains the existing finite eviction policy. → [ADR 0219](../decisions/0219-journal-damage-is-data-and-io-failure-is-failure.md).
|
|
709
|
+
|
|
672
710
|
Shutdown performs one phase barrier at a time: stop admission everywhere,
|
|
673
711
|
cancel future schedules, drain admitted work, then close in reverse stable
|
|
674
712
|
topological order. Every hook shares the same grace deadline. Forced cleanup
|
|
@@ -854,156 +892,3 @@ The responsibility change is more important than line count:
|
|
|
854
892
|
Durable job tables, lifecycle journals/outboxes, provider inboxes and business
|
|
855
893
|
retry rules do **not** disappear. They were never process-local glue and remain
|
|
856
894
|
application-owned.
|
|
857
|
-
|
|
858
|
-
## Durable process facts and owner notifications
|
|
859
|
-
|
|
860
|
-
`createProcessLifecycleLedger` records a bounded versioned list of process runs.
|
|
861
|
-
Start, readiness, draining and shutdown target both `runId` and `pid`, so hot
|
|
862
|
-
reload and PID reuse cannot close the wrong generation. `lifecycleLedgerResource`
|
|
863
|
-
drives it from the kernel's phases: `start` records the start, `activate` the
|
|
864
|
-
readiness, `stopAdmission` the drain — the run's `unavailableAt`, the moment it
|
|
865
|
-
stops answering new work — and `close` / `force` the stop. A run that stops
|
|
866
|
-
without ever becoming ready (a failed startup rolls back with `close` only)
|
|
867
|
-
ends as `startup-failed`, not `clean`.
|
|
868
|
-
|
|
869
|
-
A start classifies what happened to the newest run before it, and the
|
|
870
|
-
classification is decided by four facts — whether that run recorded its own
|
|
871
|
-
exit, whether the pid is the same, whether the version changed and whether it
|
|
872
|
-
ever became ready:
|
|
873
|
-
|
|
874
|
-
| newest run | same pid | version | `previousExit` | predecessor's `termination` |
|
|
875
|
-
|---|---|---|---|---|
|
|
876
|
-
| none | — | — | `first-boot` | — |
|
|
877
|
-
| recorded `stoppedAt` | — | — | `clean` / `forced` / `startup-failed` / `abnormal` as recorded | unchanged |
|
|
878
|
-
| still open | yes | — | `hot-reload` | `hot-reload`, closed at the new start |
|
|
879
|
-
| still open | no | changed | `handoff` (default) | stays open; it records its own stop later |
|
|
880
|
-
| still open | no | changed, `versionChangeOverlap: 'abnormal'` | `abnormal` / `startup-failed` | closed at the new start, as for the same version |
|
|
881
|
-
| still open, was ready | no | same | `abnormal` (default) | `abnormal`, closed at the new start — an upper bound, the crash time is unknown |
|
|
882
|
-
| still open, never ready | no | same | `startup-failed` (default) | `startup-failed`, closed at the new start |
|
|
883
|
-
|
|
884
|
-
Every other open run the start finds was abandoned too and is closed the same
|
|
885
|
-
way — two crashes in a row leave two open runs, and both are closed, not only
|
|
886
|
-
the newest. Open means `active` or `draining`.
|
|
887
|
-
|
|
888
|
-
A version of `unknown` on either side is never a version change, so a dev build
|
|
889
|
-
after a crashed release reads `abnormal`, not `handoff`. `forced` means the
|
|
890
|
-
process itself acknowledged a kill; `abnormal` means a successor found it dead.
|
|
891
|
-
|
|
892
|
-
### Downtime is the window nobody answered in
|
|
893
|
-
|
|
894
|
-
`ReadyFact.downtimeMs` is `readyAt` of the new run minus `unavailableAt` of the
|
|
895
|
-
last run that served — the predecessor's drain plus the successor's boot. A
|
|
896
|
-
110 s forced drain followed by a 4 s boot is 114 s of downtime; the gap between
|
|
897
|
-
the two processes alone would read 4 s before and after that defect was fixed.
|
|
898
|
-
Runs that never became ready answered nobody, so the count passes them: after a
|
|
899
|
-
failed start it still opens where the last serving run stopped answering. It is
|
|
900
|
-
`0` when that run still answers (a handoff whose predecessor has not drained
|
|
901
|
-
yet) and `null` on first boot and when the end was never timed — a crash or a
|
|
902
|
-
hot reload records no `unavailableAt`. `unavailableSince` names the moment it is
|
|
903
|
-
counted from. The gap between two processes is still there, under its own
|
|
904
|
-
name: `StartFact.processGapMs` is the start minus the predecessor's recorded
|
|
905
|
-
stop.
|
|
906
|
-
|
|
907
|
-
The ledger records what the process says while it can say it. stitchkit never
|
|
908
|
-
calls `process.exit` (ADR 0074), so a stop is recorded on the kernel's `close`
|
|
909
|
-
or `force` path, both awaited. An application that exits the process on its
|
|
910
|
-
own before its shutdown settles loses that last write; the successor then
|
|
911
|
-
finds the run open and closes it as `abnormal`, keeping the `unavailableAt`
|
|
912
|
-
already recorded — which is why the drain moment is written first, at
|
|
913
|
-
`stopAdmission`, and the downtime survives a stop that was never recorded.
|
|
914
|
-
|
|
915
|
-
The `abnormal` default is a choice, and it is the single-process deployment:
|
|
916
|
-
one process per build, a new pid of the same build means the old one stopped
|
|
917
|
-
answering. Where processes of **one** build overlap on purpose — a cluster, a
|
|
918
|
-
zero-downtime reload of the same build — pass `sameVersionOverlap: 'handoff'`
|
|
919
|
-
to the ledger, and every open run stays open until it records its own
|
|
920
|
-
shutdown. The cost of that setting is symmetric: a real crash under it is
|
|
921
|
-
reported as a handoff and the dead run stays open in the ledger until
|
|
922
|
-
retention drops it.
|
|
923
|
-
|
|
924
|
-
A version change is the other axis, and its default is the opposite:
|
|
925
|
-
`handoff`, because a release that starts the new build before stopping the
|
|
926
|
-
old one is the common zero-downtime shape. Where builds never overlap — one
|
|
927
|
-
process per deployment (a pm2 fork, a systemd unit, one container), the old
|
|
928
|
-
one stopped before the new one starts — pass `versionChangeOverlap:
|
|
929
|
-
'abnormal'`. An open predecessor of another build then died without
|
|
930
|
-
recording its exit, most often killed during the release itself: it is closed
|
|
931
|
-
as `abnormal` (or `startup-failed`) at the new start, `downtimeMs` is `null`
|
|
932
|
-
instead of `0`, and `previousVersion` / `versionChanged` still describe the
|
|
933
|
-
release. A predecessor that did record its stop is read as before, and its
|
|
934
|
-
downtime is measured. The two settings compose: `sameVersionOverlap:
|
|
935
|
-
'handoff'` keeps open only the runs of a build allowed to overlap the new one.
|
|
936
|
-
|
|
937
|
-
The list is kept in the order the transitions wrote it —
|
|
938
|
-
every write goes through one atomic update, so that order is the causal one,
|
|
939
|
-
and a successor whose clock lags its predecessor still finds it at the head;
|
|
940
|
-
`startedAt` is data, not the sort key. Retention (`retain`, default 20) drops
|
|
941
|
-
finished runs first and an open one — a live handoff predecessor — only when
|
|
942
|
-
nothing finished is left. Facts are published through the ledger's own
|
|
943
|
-
subscription and resource value; `ApplicationEventSink` remains the strict
|
|
944
|
-
application-state stream.
|
|
945
|
-
|
|
946
|
-
`createNotificationOutbox` is the transport-neutral durable delivery side. It
|
|
947
|
-
persists before send, claims an item with an expiring lease, carries one stable
|
|
948
|
-
idempotency key into the transport, retries under an injected clock and records
|
|
949
|
-
terminal drops. The guarantee is at-least-once: a crash after remote acceptance
|
|
950
|
-
but before the receipt is persisted may redeliver, so transports should use the
|
|
951
|
-
key when they support deduplication. The retry budget is sized for the outage
|
|
952
|
-
an owner notification has to outlive, not for a flaky call: the default backoff
|
|
953
|
-
doubles from one second and caps at sixty (`backoffDelay`, the one formula the
|
|
954
|
-
client's resumable streams also use, with jitter 0), and the 99 waits between
|
|
955
|
-
the default `maxAttempts` of 100 sum to 1+2+4+8+16+32 s plus 93 × 60 s — about
|
|
956
|
-
94 minutes — before `onDropped` sees `attempt-limit`.
|
|
957
|
-
`state()` is a read and never fails on the bounds a transition enforces — a file
|
|
958
|
-
that grew past `maxStateBytes` under an older limit is inspectable and is
|
|
959
|
-
trimmed by the next transition. Two bounds do fail loudly: `enqueue` past
|
|
960
|
-
`maxQueue` throws rather than dropping silently, and a `backoffMs` that returns
|
|
961
|
-
`NaN`, a negative or an infinite delay rejects the flush. `stop()` lets the
|
|
962
|
-
send in flight finish and claims nothing more; a `send` without its own
|
|
963
|
-
deadline holds `stop()` — and so the resource's `force()` — for that one call,
|
|
964
|
-
so give the transport a timeout. Superseding a key that is being sent right now
|
|
965
|
-
does not recall it: the send completes, and only its receipt is not written.
|
|
966
|
-
|
|
967
|
-
`createDirectoryInbox` is the receiving side for another program on the same
|
|
968
|
-
host: it drops entries — a release transition, say — into a directory, and
|
|
969
|
-
the application takes each one at least once. It is a managed resource of its
|
|
970
|
-
own (`createDirectoryInbox({ id, directory, schema, handle })`, imported from
|
|
971
|
-
`stitchkit/application/directory-inbox` because it touches files; its types
|
|
972
|
-
and schemas are in `stitchkit/application`) and publishes a handle with
|
|
973
|
-
`flush()` and `state()`. The producer writes each entry
|
|
974
|
-
atomically as `<name>.json` — a temporary name, then a rename; names that start
|
|
975
|
-
with a dot are never read. Entries are delivered in name order, and only after
|
|
976
|
-
`activate`: none reaches the application before it is ready. `stopAdmission`
|
|
977
|
-
stops taking new ones, `drain` waits for the one in flight, and `force` aborts
|
|
978
|
-
the `signal` its handler was given.
|
|
979
|
-
|
|
980
|
-
Taken and done are separate durable records. Before `handle` runs, the entry
|
|
981
|
-
is claimed with a lease (`leaseMs`, default five minutes); after it returns,
|
|
982
|
-
a receipt replaces the claim and only then is the file removed. A process that
|
|
983
|
-
died mid-delivery leaves a claim, and the entry is taken again once the lease
|
|
984
|
-
runs out — at least once, not exactly once, so a handler that sends somewhere
|
|
985
|
-
should carry the entry's `key` as its idempotency key. A process that died
|
|
986
|
-
after the receipt leaves only the file, which the next pass removes without
|
|
987
|
-
delivering it again. A handler that throws is retried after a backoff from one
|
|
988
|
-
second doubling to five minutes; an entry that fails `schema`, is over
|
|
989
|
-
`maxEntryBytes` or was taken `maxAttempts` times (default 20 — the count
|
|
990
|
-
survives restarts, so an entry whose handling kills the process is not taken
|
|
991
|
-
forever) is moved to `rejected/` with its reason and reported to `onRejected`,
|
|
992
|
-
and the entries after it keep flowing. The state lives in
|
|
993
|
-
`<directory>/.inbox-state.json` under `createFileStateStore`'s inter-process
|
|
994
|
-
lock unless a `store` is supplied.
|
|
995
|
-
|
|
996
|
-
These primitives depend on the structural `StateStore`. On a server,
|
|
997
|
-
`createFileStateStore` supplies the shared Zod-validated JSON adapter with an
|
|
998
|
-
inter-process lock, unique temporary file, fsync and atomic rename. The lock
|
|
999
|
-
is a file with a heartbeat: the holder refreshes its mtime every third of
|
|
1000
|
-
`staleLockMs` (default 3 s), a contender waits up to `lockTimeoutMs` (default
|
|
1001
|
-
10 s), and the stale bound must sit inside the timeout — otherwise a crashed
|
|
1002
|
-
holder blocks every update until the lock ages out, which the constructor
|
|
1003
|
-
refuses. A lock whose heartbeat is stale is reclaimed once its recorded pid is
|
|
1004
|
-
gone; a live or unverifiable pid (a reused number, another user's process)
|
|
1005
|
-
keeps it for ten stale bounds — and never fewer than thirty missed heartbeats,
|
|
1006
|
-
so a scheduler stall on a loaded host cannot pull a live lock from under its
|
|
1007
|
-
holder — after which the heartbeat wins and the lock is abandoned. Temporary files a crashed writer left beside the state are swept on
|
|
1008
|
-
the store's first update. Ledger corruption may be declared reconstructable;
|
|
1009
|
-
an outbox must fail closed rather than silently discard pending delivery.
|
package/llms/stitchkit.txt
CHANGED
|
@@ -79,26 +79,29 @@ own, recorded as an ADR.
|
|
|
79
79
|
| `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
|
|
80
80
|
| `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
|
|
81
81
|
| `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
|
|
82
|
-
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the
|
|
82
|
+
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the 48 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
83
83
|
| `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
|
|
84
84
|
| `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
85
85
|
| `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
|
|
86
86
|
| `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
|
|
87
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the
|
|
87
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 48 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
88
88
|
| `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
|
|
89
89
|
| `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
|
|
90
90
|
| `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
|
|
91
91
|
| `stitchkit/agent-runtime/coding-tools` | server (Bun or Node) | evolving | bounded host-authorized direct file and shell tools; a root boundary, not an OS sandbox |
|
|
92
92
|
| `stitchkit/agent-runtime/openrouter` | server | evolving | isolated OpenRouter language-model adapter |
|
|
93
|
-
| `stitchkit/agent-runtime/browser` | browser + server | evolving | canonical agent records, events
|
|
93
|
+
| `stitchkit/agent-runtime/browser` | browser + server | evolving | canonical agent records, events, reconnect cursor and optional conversation controller |
|
|
94
|
+
| `stitchkit/agent-runtime/harness-tools` | server | evolving | full mountAgent configuration with the current run fence |
|
|
95
|
+
| `stitchkit/agent-runtime/react` | browser + server | evolving | React subscription to an application-owned agent controller |
|
|
96
|
+
| `stitchkit/agent-runtime/realtime` | server (Bun or Node) | evolving | authorized agent control over the existing Socket.IO server |
|
|
94
97
|
| `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
|
|
95
98
|
| `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
|
|
96
99
|
| `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
|
|
97
|
-
| `stitchkit/application` | browser + server | evolving<br>_redefined in
|
|
100
|
+
| `stitchkit/application` | browser + server | evolving<br>_redefined in 11 of the 48 minors since 0.56.2, most recently 0.103.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
|
|
98
101
|
| `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
|
|
99
102
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
100
103
|
| `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
|
|
101
|
-
| `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal —
|
|
104
|
+
| `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal — an exclusive bounded writer and snapshot reader with explicit anomalies |
|
|
102
105
|
| `stitchkit/application/directory-inbox` | server | evolving | the directory inbox — entries another program drops into a directory, delivered to the application at least once |
|
|
103
106
|
|
|
104
107
|
Rule of thumb: browser code imports `stitchkit` and `stitchkit/react`; server
|
|
@@ -200,6 +203,7 @@ map — feature → packages:
|
|
|
200
203
|
| MCP / agent adapters (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
|
|
201
204
|
| Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
|
|
202
205
|
| Headless Agent harness (`stitchkit/agent-runtime/harness`) | `ai` |
|
|
206
|
+
| Harness tools (`stitchkit/agent-runtime/harness-tools`) | `ai` `@modelcontextprotocol/server` (tool declarations) |
|
|
203
207
|
| Agent coding tools (`stitchkit/agent-runtime/coding-tools`) | — |
|
|
204
208
|
| OpenRouter runtime adapter (`stitchkit/agent-runtime/openrouter`) | `ai` `@openrouter/ai-sdk-provider` |
|
|
205
209
|
| SQLite agent store (`stitchkit/agent-runtime/sqlite/bun` or `/node`) | — (runtime built-in) |
|
|
@@ -1,14 +1,43 @@
|
|
|
1
|
-
# Upgrading 0.75.0 → 0.
|
|
1
|
+
# Upgrading 0.75.0 → 0.103.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.75.0 → 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.75.0 → 0.
|
|
9
|
+
# Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.103.0
|
|
13
|
+
|
|
14
|
+
### Diagnostic journal startup preserves torn evidence and inspects archives
|
|
15
|
+
|
|
16
|
+
**Who must act:** operators using `maxFiles: 1` who can encounter a torn active
|
|
17
|
+
file, or whose retained files are unreadable by the writer. Clean single-file
|
|
18
|
+
journals continue to work; successful startup now requires read access to every
|
|
19
|
+
retained generation.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
|
|
23
|
+
|
|
24
|
+
// Before: a torn active file could be discarded during startup.
|
|
25
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
|
|
26
|
+
// After: retain the torn file while the fresh writer starts in a new active file.
|
|
27
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
|
|
31
|
+
from `stitchkit/application`, carrying `recovery` observations and releasing its lock
|
|
32
|
+
without deleting evidence. Inspection I/O errors also fail startup and release the
|
|
33
|
+
lock; restore filesystem access rather than treating that failure as a bad JSON row.
|
|
34
|
+
Normal rotation retains the configured finite eviction policy.
|
|
35
|
+
|
|
36
|
+
For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
|
|
37
|
+
from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
|
|
38
|
+
missing files, permissions and unsafe paths still throw. See the
|
|
39
|
+
[journal guide](application-kernel.md#bounded-local-diagnostic-journal).
|
|
40
|
+
|
|
12
41
|
## Released migration: 0.102.0
|
|
13
42
|
|
|
14
43
|
### `view_file` receives an array, not an array encoded as text
|
package/llms/upgrading.txt
CHANGED
|
@@ -11,7 +11,7 @@ Contains: Guide: Upgrading, general (docs/guide/upgrading.md)
|
|
|
11
11
|
|
|
12
12
|
Load this slice, then every range slice between your installed version and the target:
|
|
13
13
|
|
|
14
|
-
- 0.75.0 → 0.
|
|
14
|
+
- 0.75.0 → 0.103.0: `llms/upgrading-0.75.0-0.103.0.txt`
|
|
15
15
|
- 0.61.0 → 0.74.0: `llms/upgrading-0.61.0-0.74.0.txt`
|
|
16
16
|
- 0.44.0 → 0.60.0: `llms/upgrading-0.44.0-0.60.0.txt`
|
|
17
17
|
- 0.37.0 → 0.37.0: `llms/upgrading-0.37.0.txt`
|