stitchkit 0.94.1 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,64 @@
1
- # Upgrading 0.53.0 → 0.67.0 — stitchkit docs slice
1
+ # Upgrading 0.55.0 → 0.68.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.53.0 → 0.67.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.55.0 → 0.68.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.53.0 → 0.67.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.55.0 → 0.68.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.68.0
13
+
14
+ ### Make Unix transport selection explicit outside Bun
15
+
16
+ The legacy `unix` option remains a Bun convenience, but on Node or another
17
+ runtime it now fails before dispatch. Replace it with the owned adapter and close
18
+ that adapter with the application:
19
+
20
+ ```ts
21
+ // before — unsafe outside Bun: an unsupported fetch could dial baseUrl over TCP
22
+ const http = createHttpClient({ baseUrl, unix: '/run/service.sock' })
23
+
24
+ // after — Bun and Node; every dispatch and redirect stays on the socket
25
+ import { createUnixClientTransport } from 'stitchkit/server' // or stitchkit/node
26
+ const transport = createUnixClientTransport({ socketPath: '/run/service.sock' })
27
+ const http = createHttpClient({ baseUrl, fetch: transport.fetch })
28
+ // during shutdown
29
+ await transport.close()
30
+ ```
31
+
32
+ Do not automatically replay `possibly-dispatched`: a timeout or connection loss
33
+ after bytes left the process does not prove that a write did not happen.
34
+
35
+ ### Choose tolerant stream parsing explicitly
36
+
37
+ `parseNDJSON` and `parseSSE` now throw on malformed JSON, invalid UTF-8 and an
38
+ over-limit line. The default line ceiling is 1 MiB. If a feed deliberately skips
39
+ bad records, retain that policy explicitly:
40
+
41
+ ```ts
42
+ // before — malformed input disappeared implicitly
43
+ parseNDJSON(response)
44
+
45
+ // after — ordinary fail-closed path
46
+ parseNDJSON(response, { maxLineBytes: 256 * 1024 })
47
+
48
+ // after — deliberately tolerant path
49
+ parseNDJSON(response, { onParseError: (raw, error) => report(raw, error) })
50
+ ```
51
+
52
+ ### Extend exhaustive framework-error handling
53
+
54
+ If a switch makes `StitchErrorCode` exhaustive, add
55
+ `STREAM_ITEM_INVALID`, `STREAM_FRAME_TOO_LARGE`,
56
+ `STREAM_TERMINAL_MISSING` and `STREAM_LIFETIME_EXCEEDED`. A partial application
57
+ status map needs no change (ADR 0105).
58
+
59
+ The admission/channel APIs and endpoint `stream` descriptor are additive; raw
60
+ responses and raw `streamingRoute` remain supported.
61
+
12
62
  ## Released migration: 0.67.0
13
63
 
14
64
  Three application-kernel changes. Two of them fix silent failures, so the most
@@ -1150,25 +1200,3 @@ Downloaded `path` is now relative to the boundary and MIME metadata is named
1150
1200
  same way. Auth predicates must explicitly return `true`, `false`, or a plain
1151
1201
  object of context fields; replace accidental `undefined` fallthroughs with the
1152
1202
  intended boolean.
1153
-
1154
- ## Released migration: 0.53.0
1155
-
1156
- ### Realtime `emit` returns `boolean` instead of `void`
1157
-
1158
- Every **call site** compiles and behaves exactly as before — the return value
1159
- is new information (`true` = accepted by the transport, `false` = dropped
1160
- while the browser client was disconnected), not a behavior change. What breaks
1161
- is **implementing** the interfaces: a test mock or app-side adapter of
1162
- `SocketIOClient` / `RealtimeClient` / `ValidatedRealtimeSocket` /
1163
- `RealtimeServer` whose `emit` returns `void` no longer typechecks.
1164
-
1165
- ```ts
1166
- // before — a void mock satisfied the interface
1167
- const mock: Pick<RealtimeClient<S, C>, 'emit'> = { emit: () => {} }
1168
- // after — report acceptance (true is what a live server-side emit reports)
1169
- const mock: Pick<RealtimeClient<S, C>, 'emit'> = { emit: () => true }
1170
- ```
1171
-
1172
- While migrating, consider replacing hand-rolled `if (client.connected)` guards
1173
- with the new honest surface: check `client.emit(...) === false`, or observe
1174
- drops centrally with `onDroppedEmit`.
@@ -1,14 +1,56 @@
1
- # Upgrading 0.68.0 → 0.94.0 — stitchkit docs slice
1
+ # Upgrading 0.69.0 → 0.95.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.68.0 → 0.94.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.69.0 → 0.95.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.68.0 → 0.94.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.69.0 → 0.95.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.95.0
13
+
14
+ One breaking change in `stitchkit/application`: the process lifecycle ledger
15
+ counts downtime as the window nobody answered in, and gains the `draining`
16
+ phase and the `startup-failed` outcome. A ledger file written by an earlier
17
+ version loads unchanged — the new `unavailableAt` reads as `null`.
18
+
19
+ 1. **Read downtime from the ready fact.** **Who must act:** a project that
20
+ reads `downtimeMs` from a `started` fact. It is gone from `StartFact`; the
21
+ number it carried is `processGapMs`. The downtime now arrives with the new
22
+ run's readiness:
23
+
24
+ ```ts
25
+ // before
26
+ ledger.subscribe((fact) => {
27
+ if (fact.type === 'started') report(fact.previousExit, fact.downtimeMs);
28
+ });
29
+ // after
30
+ ledger.subscribe((fact) => {
31
+ if (fact.type === 'started') previousExit = fact.previousExit;
32
+ if (fact.type === 'ready') report(previousExit, fact.downtimeMs);
33
+ });
34
+ ```
35
+
36
+ 2. **Handle the new values.** **Who must act:** a project that switches
37
+ exhaustively over `LifecycleTermination` (new: `draining`,
38
+ `startup-failed`), `PreviousExit` (new: `startup-failed`) or
39
+ `ProcessLifecycleFact` (new: `DrainingFact`, `type: 'draining'`). The type
40
+ checker names each switch. An open run is `active` or `draining`; a check
41
+ written as `termination === 'active'` to mean "still running" becomes
42
+ `termination === 'active' || termination === 'draining'`.
43
+ `TransitionReadyInput` is renamed `TransitionRunInput` — the same fields,
44
+ now also taken by `transitionProcessDraining`; rename the import.
45
+
46
+ 3. **Record the drain and the readiness when driving the ledger by hand.**
47
+ **Who must act:** only a project that calls `createProcessLifecycleLedger`
48
+ methods itself instead of mounting `lifecycleLedgerResource`. Call
49
+ `recordDraining()` where the application stops admitting work, before it
50
+ drains; without it downtime is counted from the recorded stop. Call
51
+ `recordReady()` when the run serves; a run stopped without it now ends
52
+ `startup-failed`, not `clean`.
53
+
12
54
  ## Released migration: 0.94.0
13
55
 
14
56
  One breaking minor that consolidates: tool options move into one group, and
@@ -1107,53 +1149,3 @@ else renderExistingRole(message)
1107
1149
 
1108
1150
  No data migration is needed. The schema still accepts all earlier records, and applications that
1109
1151
  do not exhaustively branch over these unions compile unchanged.
1110
-
1111
- ## Released migration: 0.68.0
1112
-
1113
- ### Make Unix transport selection explicit outside Bun
1114
-
1115
- The legacy `unix` option remains a Bun convenience, but on Node or another
1116
- runtime it now fails before dispatch. Replace it with the owned adapter and close
1117
- that adapter with the application:
1118
-
1119
- ```ts
1120
- // before — unsafe outside Bun: an unsupported fetch could dial baseUrl over TCP
1121
- const http = createHttpClient({ baseUrl, unix: '/run/service.sock' })
1122
-
1123
- // after — Bun and Node; every dispatch and redirect stays on the socket
1124
- import { createUnixClientTransport } from 'stitchkit/server' // or stitchkit/node
1125
- const transport = createUnixClientTransport({ socketPath: '/run/service.sock' })
1126
- const http = createHttpClient({ baseUrl, fetch: transport.fetch })
1127
- // during shutdown
1128
- await transport.close()
1129
- ```
1130
-
1131
- Do not automatically replay `possibly-dispatched`: a timeout or connection loss
1132
- after bytes left the process does not prove that a write did not happen.
1133
-
1134
- ### Choose tolerant stream parsing explicitly
1135
-
1136
- `parseNDJSON` and `parseSSE` now throw on malformed JSON, invalid UTF-8 and an
1137
- over-limit line. The default line ceiling is 1 MiB. If a feed deliberately skips
1138
- bad records, retain that policy explicitly:
1139
-
1140
- ```ts
1141
- // before — malformed input disappeared implicitly
1142
- parseNDJSON(response)
1143
-
1144
- // after — ordinary fail-closed path
1145
- parseNDJSON(response, { maxLineBytes: 256 * 1024 })
1146
-
1147
- // after — deliberately tolerant path
1148
- parseNDJSON(response, { onParseError: (raw, error) => report(raw, error) })
1149
- ```
1150
-
1151
- ### Extend exhaustive framework-error handling
1152
-
1153
- If a switch makes `StitchErrorCode` exhaustive, add
1154
- `STREAM_ITEM_INVALID`, `STREAM_FRAME_TOO_LARGE`,
1155
- `STREAM_TERMINAL_MISSING` and `STREAM_LIFETIME_EXCEEDED`. A partial application
1156
- status map needs no change (ADR 0105).
1157
-
1158
- The admission/channel APIs and endpoint `stream` descriptor are additive; raw
1159
- responses and raw `streamingRoute` remain supported.
@@ -11,9 +11,9 @@ 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.68.0 → 0.94.0: `llms/upgrading-0.68.0-0.94.0.txt`
15
- - 0.53.0 → 0.67.0: `llms/upgrading-0.53.0-0.67.0.txt`
16
- - 0.37.0 → 0.50.0: `llms/upgrading-0.37.0-0.50.0.txt`
14
+ - 0.69.0 → 0.95.0: `llms/upgrading-0.69.0-0.95.0.txt`
15
+ - 0.55.0 → 0.68.0: `llms/upgrading-0.55.0-0.68.0.txt`
16
+ - 0.37.0 → 0.53.0: `llms/upgrading-0.37.0-0.53.0.txt`
17
17
 
18
18
  # Upgrading stitchkit
19
19
 
package/llms-full.txt CHANGED
@@ -67,11 +67,11 @@ own, recorded as an ADR.
67
67
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
68
68
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
69
69
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
70
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 39 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
70
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 40 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
71
71
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
72
72
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
73
73
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
74
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 21 of the 39 minors since 0.56.2, most recently 0.94.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
74
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 21 of the 40 minors since 0.56.2, most recently 0.94.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
75
75
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
76
76
  | `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 |
77
77
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -81,7 +81,7 @@ own, recorded as an ADR.
81
81
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
82
82
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
83
83
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
84
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 7 of the 39 minors since 0.56.2, most recently 0.83.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
84
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 8 of the 40 minors since 0.56.2, most recently 0.95.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
85
85
  | `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
86
86
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
87
87
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -7061,39 +7061,74 @@ application-owned.
7061
7061
  ## Durable process facts and owner notifications
7062
7062
 
7063
7063
  `createProcessLifecycleLedger` records a bounded versioned list of process runs.
7064
- Start, readiness and shutdown target both `runId` and `pid`, so hot reload and
7065
- PID reuse cannot close the wrong generation. A start classifies what happened to
7066
- the newest run before it, and the classification is decided by three facts —
7067
- whether that run recorded its own exit, whether the pid is the same, and whether
7068
- the version changed:
7064
+ Start, readiness, draining and shutdown target both `runId` and `pid`, so hot
7065
+ reload and PID reuse cannot close the wrong generation. `lifecycleLedgerResource`
7066
+ drives it from the kernel's phases: `start` records the start, `activate` the
7067
+ readiness, `stopAdmission` the drain — the run's `unavailableAt`, the moment it
7068
+ stops answering new work — and `close` / `force` the stop. A run that stops
7069
+ without ever becoming ready (a failed startup rolls back with `close` only)
7070
+ ends as `startup-failed`, not `clean`.
7071
+
7072
+ A start classifies what happened to the newest run before it, and the
7073
+ classification is decided by four facts — whether that run recorded its own
7074
+ exit, whether the pid is the same, whether the version changed and whether it
7075
+ ever became ready:
7069
7076
 
7070
7077
  | newest run | same pid | version | `previousExit` | predecessor's `termination` |
7071
7078
  |---|---|---|---|---|
7072
7079
  | none | — | — | `first-boot` | — |
7073
- | recorded `stoppedAt` | — | — | `clean` / `forced` / `abnormal` as recorded | unchanged |
7074
- | still `active` | yes | — | `hot-reload` | `hot-reload`, closed at the new start |
7075
- | still `active` | no | changed | `handoff` | stays `active`; it records its own stop later |
7076
- | still `active` | no | same | `abnormal` (default) | `abnormal`, closed at the new start — an upper bound, the crash time is unknown |
7080
+ | recorded `stoppedAt` | — | — | `clean` / `forced` / `startup-failed` / `abnormal` as recorded | unchanged |
7081
+ | still open | yes | — | `hot-reload` | `hot-reload`, closed at the new start |
7082
+ | still open | no | changed | `handoff` | stays open; it records its own stop later |
7083
+ | still open, was ready | no | same | `abnormal` (default) | `abnormal`, closed at the new start — an upper bound, the crash time is unknown |
7084
+ | still open, never ready | no | same | `startup-failed` (default) | `startup-failed`, closed at the new start |
7085
+
7086
+ Every other open run the start finds was abandoned too and is closed the same
7087
+ way — two crashes in a row leave two open runs, and both are closed, not only
7088
+ the newest. Open means `active` or `draining`.
7077
7089
 
7078
7090
  A version of `unknown` on either side is never a version change, so a dev build
7079
7091
  after a crashed release reads `abnormal`, not `handoff`. `forced` means the
7080
7092
  process itself acknowledged a kill; `abnormal` means a successor found it dead.
7081
7093
 
7082
- The last row is a choice, and the default is the single-process deployment:
7094
+ ### Downtime is the window nobody answered in
7095
+
7096
+ `ReadyFact.downtimeMs` is `readyAt` of the new run minus `unavailableAt` of the
7097
+ last run that served — the predecessor's drain plus the successor's boot. A
7098
+ 110 s forced drain followed by a 4 s boot is 114 s of downtime; the gap between
7099
+ the two processes alone would read 4 s before and after that defect was fixed.
7100
+ Runs that never became ready answered nobody, so the count passes them: after a
7101
+ failed start it still opens where the last serving run stopped answering. It is
7102
+ `0` when that run still answers (a handoff whose predecessor has not drained
7103
+ yet) and `null` on first boot and when the end was never timed — a crash or a
7104
+ hot reload records no `unavailableAt`. `unavailableSince` names the moment it is
7105
+ counted from. The gap between two processes is still there, under its own
7106
+ name: `StartFact.processGapMs` is the start minus the predecessor's recorded
7107
+ stop.
7108
+
7109
+ The ledger records what the process says while it can say it. stitchkit never
7110
+ calls `process.exit` (ADR 0074), so a stop is recorded on the kernel's `close`
7111
+ or `force` path, both awaited. An application that exits the process on its
7112
+ own before its shutdown settles loses that last write; the successor then
7113
+ finds the run open and closes it as `abnormal`, keeping the `unavailableAt`
7114
+ already recorded — which is why the drain moment is written first, at
7115
+ `stopAdmission`, and the downtime survives a stop that was never recorded.
7116
+
7117
+ The `abnormal` default is a choice, and it is the single-process deployment:
7083
7118
  one process per build, a new pid of the same build means the old one stopped
7084
- answering. Where two processes of **one** build overlap on purpose — a
7085
- cluster, a zero-downtime reload of the same build — pass
7086
- `sameVersionOverlap: 'handoff'` to the ledger, and the predecessor stays
7087
- `active` until it records its own shutdown. The cost of that setting is
7088
- symmetric: a real crash under it is reported as a handoff and the dead run
7089
- stays `active` in the ledger until retention drops it. The list is kept in the
7090
- order the transitions wrote it — every write goes through one atomic update,
7091
- so that order is the causal one, and a successor whose clock lags its
7092
- predecessor still finds it at the head; `startedAt` is data, not the sort key.
7093
- Retention (`retain`, default 20) drops finished runs first and an active one —
7094
- a live handoff predecessor — only when nothing finished is left. Facts are
7095
- published through the ledger's own subscription and resource value;
7096
- `ApplicationEventSink` remains the strict application-state stream.
7119
+ answering. Where processes of **one** build overlap on purpose — a cluster, a
7120
+ zero-downtime reload of the same build — pass `sameVersionOverlap: 'handoff'`
7121
+ to the ledger, and every open run stays open until it records its own
7122
+ shutdown. The cost of that setting is symmetric: a real crash under it is
7123
+ reported as a handoff and the dead run stays open in the ledger until
7124
+ retention drops it. The list is kept in the order the transitions wrote it —
7125
+ every write goes through one atomic update, so that order is the causal one,
7126
+ and a successor whose clock lags its predecessor still finds it at the head;
7127
+ `startedAt` is data, not the sort key. Retention (`retain`, default 20) drops
7128
+ finished runs first and an open one — a live handoff predecessor — only when
7129
+ nothing finished is left. Facts are published through the ledger's own
7130
+ subscription and resource value; `ApplicationEventSink` remains the strict
7131
+ application-state stream.
7097
7132
 
7098
7133
  `createNotificationOutbox` is the transport-neutral durable delivery side. It
7099
7134
  persists before send, claims an item with an expiring lease, carries one stable
@@ -12664,6 +12699,48 @@ analytics policy belong to the application.
12664
12699
 
12665
12700
  # Upgrading stitchkit
12666
12701
 
12702
+ ## Released migration: 0.95.0
12703
+
12704
+ One breaking change in `stitchkit/application`: the process lifecycle ledger
12705
+ counts downtime as the window nobody answered in, and gains the `draining`
12706
+ phase and the `startup-failed` outcome. A ledger file written by an earlier
12707
+ version loads unchanged — the new `unavailableAt` reads as `null`.
12708
+
12709
+ 1. **Read downtime from the ready fact.** **Who must act:** a project that
12710
+ reads `downtimeMs` from a `started` fact. It is gone from `StartFact`; the
12711
+ number it carried is `processGapMs`. The downtime now arrives with the new
12712
+ run's readiness:
12713
+
12714
+ ```ts
12715
+ // before
12716
+ ledger.subscribe((fact) => {
12717
+ if (fact.type === 'started') report(fact.previousExit, fact.downtimeMs);
12718
+ });
12719
+ // after
12720
+ ledger.subscribe((fact) => {
12721
+ if (fact.type === 'started') previousExit = fact.previousExit;
12722
+ if (fact.type === 'ready') report(previousExit, fact.downtimeMs);
12723
+ });
12724
+ ```
12725
+
12726
+ 2. **Handle the new values.** **Who must act:** a project that switches
12727
+ exhaustively over `LifecycleTermination` (new: `draining`,
12728
+ `startup-failed`), `PreviousExit` (new: `startup-failed`) or
12729
+ `ProcessLifecycleFact` (new: `DrainingFact`, `type: 'draining'`). The type
12730
+ checker names each switch. An open run is `active` or `draining`; a check
12731
+ written as `termination === 'active'` to mean "still running" becomes
12732
+ `termination === 'active' || termination === 'draining'`.
12733
+ `TransitionReadyInput` is renamed `TransitionRunInput` — the same fields,
12734
+ now also taken by `transitionProcessDraining`; rename the import.
12735
+
12736
+ 3. **Record the drain and the readiness when driving the ledger by hand.**
12737
+ **Who must act:** only a project that calls `createProcessLifecycleLedger`
12738
+ methods itself instead of mounting `lifecycleLedgerResource`. Call
12739
+ `recordDraining()` where the application stops admitting work, before it
12740
+ drains; without it downtime is counted from the recorded stop. Call
12741
+ `recordReady()` when the run serves; a run stopped without it now ends
12742
+ `startup-failed`, not `clean`.
12743
+
12667
12744
  ## Released migration: 0.94.0
12668
12745
 
12669
12746
  One breaking minor that consolidates: tool options move into one group, and
@@ -16892,11 +16969,11 @@ cutovers are covered by the executable
16892
16969
  | `createApplication` | function | compose a validated resource DAG into one startup, readiness, admission and shutdown state machine |
16893
16970
  | `StateStore` / `StateStoreUpdate` | _type_ | async atomic read/update boundary shared by durable application state machines |
16894
16971
  | `createProcessLifecycleLedger` / `ProcessLifecycleLedger` / `ProcessLifecycleLedgerConfig` | function / _type_ | durable bounded run history and typed fact subscription |
16895
- | `LifecycleRunSchema` / `LifecycleRun` / `LifecycleStateSchema` / `LifecycleState` / `LifecycleTerminationSchema` / `LifecycleTermination` | schema / _type_ | versioned process-run state and termination vocabulary |
16896
- | `PreviousExitSchema` / `PreviousExit` / `StartFact` / `ReadyFact` / `ShutdownFact` / `ProcessLifecycleFact` | schema / _type_ | first-boot, hot-reload, clean, forced, handoff and abnormal lifecycle facts |
16897
- | `transitionProcessStart` / `transitionProcessReady` / `transitionProcessShutdown` | function | pure idempotent runId+pid-owned transitions |
16898
- | `LifecycleTransition` / `TransitionStartInput` / `TransitionReadyInput` / `TransitionShutdownInput` / `SameVersionOverlap` | _type_ | pure transition inputs, the same-build overlap policy (`abnormal` default / `handoff`) and state+fact result |
16899
- | `lifecycleLedgerResource` / `LifecycleLedgerResource` / `LifecycleLedgerResourceConfig` | function / _type_ | managed-resource adapter that records start, readiness and shutdown |
16972
+ | `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`) |
16973
+ | `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 |
16974
+ | `transitionProcessStart` / `transitionProcessReady` / `transitionProcessDraining` / `transitionProcessShutdown` | function | pure idempotent runId+pid-owned transitions |
16975
+ | `LifecycleTransition` / `TransitionStartInput` / `TransitionRunInput` / `TransitionShutdownInput` / `SameVersionOverlap` | _type_ | pure transition inputs (`TransitionRunInput` for ready and draining, extended with `forced` for shutdown), the same-build overlap policy (`abnormal` default / `handoff`) and state+fact result |
16976
+ | `lifecycleLedgerResource` / `LifecycleLedgerResource` / `LifecycleLedgerResourceConfig` | function / _type_ | managed-resource adapter that records start, readiness, admission stop (draining) and shutdown |
16900
16977
  | `createNotificationOutbox` / `NotificationOutbox` / `NotificationOutboxConfig` | function / _type_ | bounded at-least-once queue with durable claims, leases, retries and supersede |
16901
16978
  | `NotificationOutboxItem` / `NotificationOutboxReceipt` / `NotificationOutboxState` / `NotificationSend` / `NotificationFailureClassification` / `DroppedNotification` / `EnqueueNotification` | _type_ | versioned queue records, stable send identity and delivery decisions |
16902
16979
  | `notificationOutboxStateSchema` | function | strict persisted-state schema over an application payload schema |
package/llms.txt CHANGED
@@ -30,7 +30,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
30
30
  - **stitchkit/agent-runtime/openrouter**: [llms/agent-runtime-openrouter.txt](llms/agent-runtime-openrouter.txt) 1.1 KB
31
31
  - **stitchkit/agent-runtime/sqlite/bun**: [llms/agent-runtime-sqlite-bun.txt](llms/agent-runtime-sqlite-bun.txt) 1.8 KB
32
32
  - **stitchkit/agent-runtime/sqlite/node**: [llms/agent-runtime-sqlite-node.txt](llms/agent-runtime-sqlite-node.txt) 1.7 KB
33
- - **stitchkit/application**: [llms/application.txt](llms/application.txt) 38.0 KB → [llms/application.2.txt](llms/application.2.txt) 31.6 KB
33
+ - **stitchkit/application**: [llms/application.txt](llms/application.txt) 40.1 KB → [llms/application.2.txt](llms/application.2.txt) 31.9 KB
34
34
  - **stitchkit/application/grammy**: [llms/application-grammy.txt](llms/application-grammy.txt) 1.5 KB
35
35
  - **stitchkit/application/opentelemetry**: [llms/application-opentelemetry.txt](llms/application-opentelemetry.txt) 1.6 KB
36
36
  - **stitchkit/application/diagnostic-journal**: [llms/application-diagnostic-journal.txt](llms/application-diagnostic-journal.txt) 1.4 KB
@@ -50,9 +50,9 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
50
50
 
51
51
  ## Upgrading slices
52
52
  - **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 10.3 KB
53
- - **Upgrading 0.68.0 → 0.94.0**: [llms/upgrading-0.68.0-0.94.0.txt](llms/upgrading-0.68.0-0.94.0.txt) 46.5 KB
54
- - **Upgrading 0.53.0 → 0.67.0**: [llms/upgrading-0.53.0-0.67.0.txt](llms/upgrading-0.53.0-0.67.0.txt) 46.1 KB
55
- - **Upgrading 0.37.0 → 0.50.0**: [llms/upgrading-0.37.0-0.50.0.txt](llms/upgrading-0.37.0-0.50.0.txt) 31.6 KB
53
+ - **Upgrading 0.69.0 → 0.95.0**: [llms/upgrading-0.69.0-0.95.0.txt](llms/upgrading-0.69.0-0.95.0.txt) 46.6 KB
54
+ - **Upgrading 0.55.0 → 0.68.0**: [llms/upgrading-0.55.0-0.68.0.txt](llms/upgrading-0.55.0-0.68.0.txt) 47.0 KB
55
+ - **Upgrading 0.37.0 → 0.53.0**: [llms/upgrading-0.37.0-0.53.0.txt](llms/upgrading-0.37.0-0.53.0.txt) 32.6 KB
56
56
 
57
57
  ## Guide (web)
58
58
  - [Getting started](https://github.com/max-listov/stitchkit/blob/master/docs/guide/getting-started.md): install, entrypoints, and a first contract → server → client app
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.94.1",
3
+ "version": "0.95.0",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",