@procedures/client 0.47.1 → 0.47.2

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @procedures/client
2
2
 
3
+ ## 0.47.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 0650616: Security fix. `tokenMatches` accepted an empty presented token when the expected token was empty, so a server with `token: ""` admitted a request with an empty bearer. An empty expected token now matches nothing, so `token: ""` means "refuse each network request". The comparison now loops over the presented token, so its time depends only on what the caller sent, as its doc comment says. `MCP_HTTP_TOKEN` set and empty is now an error at the start of the HTTP face, because the server otherwise started with no token. PATCH: the change affects only a server that is open by mistake.
8
+ - ae1e3fd: Shorter doc comments.
9
+ - f1ece74: Neutral names in comments.
10
+
3
11
  ## 0.47.1
4
12
 
5
13
  ### Patch Changes
@@ -113,9 +121,9 @@ No changes in this release.
113
121
  - Each app: examine each retry rule that reads the `retryable` flag of an error. Such a rule sees the new flags of the tables. To retry a 500 of a proxy, give the retry middleware a `shouldRetry` function that matches the code `INTERNAL_ERROR`.
114
122
  - Each app with `HybridStorage` over HTTP: to make a 500 of a proxy offline again, give an `isUnavailable` option that also matches the code `INTERNAL_ERROR`.
115
123
  - The site (`packages/site`): no step. It does not match on the three old codes, and it has no retry rule for a status.
116
- - MiniMongo: do the steps of each app in its dev host and in its client code. Then examine the retry rules of its HTTP requests to the procedures server.
117
- - Graph: do the steps of each app.
118
- - jarvis: do the steps of each app in each client of `@procedures/client` that it has.
124
+ - An app: do the steps of each app in its dev host and in its client code. Then examine the retry rules of its HTTP requests to the procedures server.
125
+ - An app: do the steps of each app.
126
+ - An app: do the steps of each app in each client of `@procedures/client` that it has.
119
127
  - e4cb0cf: The release train: the ranges of @mark1russell7/algebra, @mark1russell7/service change to a version outside the old range.
120
128
 
121
129
  ### Patch Changes
@@ -173,7 +181,7 @@ No changes in this release.
173
181
 
174
182
  - A caller that reads the code of a 413 from the HTTP handler compares it with `PAYLOAD_TOO_LARGE`, not `INVALID_REQUEST`.
175
183
  - A caller of `WebSocketTransport` that retries each failed call stops at `retryable: false`. A call above the limit of the server fails the same way each time.
176
- - The site, MiniMongo, Graph and jarvis: no step, unless one of them compares the code of a refused large request with `INVALID_REQUEST`.
184
+ - Apps: no step, unless one of them compares the code of a refused large request with `INVALID_REQUEST`.
177
185
 
178
186
  ## 0.38.0
179
187
 
@@ -199,7 +207,7 @@ No changes in this release.
199
207
 
200
208
  - A caller of `cli-kit` with a `format` hook for a path with a dotted segment writes the key in the encoded form, for example `a.b%2Ec`.
201
209
  - A reader of the ecosystem scan that splits a `key` on `.` uses `keyToPath(key)`.
202
- - The site, MiniMongo, Graph and jarvis: no step, if their procedure paths have no segment with `.` or `%`.
210
+ - Apps: no step, if their procedure paths have no segment with `.` or `%`.
203
211
 
204
212
  ## 0.37.0
205
213
 
@@ -235,8 +243,8 @@ No changes in this release.
235
243
  - A reader of `changes` with a rule of the rows: apply a full answer as a replacement of the copy. The sync of `@procedures/client-store` does this. A full answer comes after each delete, so give `admitsAll` to the principals with full rights.
236
244
  - A host whose `allow` of `events.subscribe` refused a principal with a rule of the rows can admit it.
237
245
  - A host with full rights for some principals: give `admission.admitsAll`. Without it, the publisher examines each row of each event for each subscriber. Also, each write reads its rows before the change while such a subscriber is open.
238
- - Graph: give `admitsAll` for the principals that read a whole partition. Then admit the principals with a `when` condition in `allow`.
239
- - The site, MiniMongo and jarvis: no change, if their collections have no `admission.admit`. Then their events do not change.
246
+ - An app: give `admitsAll` for the principals that read a whole partition. Then admit the principals with a `when` condition in `allow`.
247
+ - Other apps: no change, if their collections have no `admission.admit`. Then their events do not change.
240
248
 
241
249
  ## 0.35.1
242
250
 
@@ -308,8 +316,8 @@ No changes in this release.
308
316
  - A host whose `expose`, policy or limit pattern names such a path in text uses the encoded form, for example `collections.e2e%2Etabs.*`.
309
317
  - An `mcpExclude` entry, an `expose` deny entry or a limit entry in the old raw form, for example `collections.e2e.tabs.drop`, does not match. The check compares the encoded key, so the procedure becomes visible, or the limit does not apply. Write each such entry in the encoded form, for example `collections.e2e%2Etabs.drop`.
310
318
  - A subscriber of a dotted collection uses `collectionChangeTopic(name)`. The raw topic `collections.a.b` is the topic of the partition `b` of `a`.
311
- - Graph: read the collection of a topic with `collectionTopicPartition(topic)`, not with a pattern, for example `/^collections\.([^.]+)\./`.
312
- - The site, MiniMongo and jarvis: no change, if their collection names have no `.` and no `%`.
319
+ - An app: read the collection of a topic with `collectionTopicPartition(topic)`, not with a pattern, for example `/^collections\.([^.]+)\./`.
320
+ - Other apps: no change, if their collection names have no `.` and no `%`.
313
321
 
314
322
  ### Patch Changes
315
323
 
@@ -326,7 +334,7 @@ No changes in this release.
326
334
 
327
335
  Migration:
328
336
 
329
- - The site, MiniMongo, Graph and jarvis: no change at this time. The deprecated names work until the next MINOR.
337
+ - Apps: no change at this time. The deprecated names work until the next MINOR.
330
338
  - Before the next MINOR, replace `zodAdapter<T>(schema)` with `schema`. To keep the check of a schema against a type, write `const schema: z.ZodType<T> = ...`.
331
339
  - Before the next MINOR, replace `typedAnySchema<T>()` and `outputSchema<T>()` with `typed<T>()`.
332
340
  - A parse-only object (`{ parse }`) in `zodAdapter` becomes a Standard Schema with a `~standard` property.
@@ -367,7 +375,7 @@ No changes in this release.
367
375
 
368
376
  Now each repetition multiplies the ways of the part inside it. The guard refuses `((a|a){9}){9}` and `((a?){9}){9}`. A pattern with few ways still passes, for example `((?:a|b){3}){3}` and `(\d{1,3}\.){3}\d{1,3}`.
369
377
 
370
- Migration: the site, MiniMongo, Graph and jarvis do not turn `$regex` on, so they need no change.
378
+ Migration: the apps do not turn `$regex` on, so they need no change.
371
379
  - 21dc858: Fixes for the security findings of the second code audit (roadmap O55).
372
380
 
373
381
  PATCH: bug fixes and additive options. Each fix refuses only an input that the documentation does not give. A caller that uses the documented behavior sees no change. A request to a loopback, private or link-local host still works, with a deprecation notice. Version 0.29.0 refuses it (decision D35).
@@ -399,7 +407,7 @@ No changes in this release.
399
407
 
400
408
  A bounded repetition with at most 1000 ways to match passes, for example `(\d{1,3}\.){3}`. Alternatives that start with different characters pass, for example `(?:foo|bar)+` and `(?:[a-z]|-)+`.
401
409
 
402
- Migration: the site, MiniMongo, Graph and jarvis do not turn `$regex` on, so they need no change. A host that turns it on and gets the new `VALIDATION_ERROR` writes the pattern without the ambiguity. For example, write `(?:a|b)+` for `(a|ab|b)+`, and write the repetitions out, `\w+\s\w+\s` for `(\w+\s){2}`.
410
+ Migration: the apps do not turn `$regex` on, so they need no change. A host that turns it on and gets the new `VALIDATION_ERROR` writes the pattern without the ambiguity. For example, write `(?:a|b)+` for `(a|ab|b)+`, and write the repetitions out, `\w+\s\w+\s` for `(\w+\s){2}`.
403
411
 
404
412
  ## 0.27.8
405
413
 
@@ -549,13 +557,13 @@ No changes in this release.
549
557
  - A face of your own that gives `mcpFace()` a handler of its own: give the handler `admission: (credentials) => server.admission(credentials)`.
550
558
  - An MCP client that a request hook refuses gets 401 at `initialize`. Give it valid credentials for each HTTP request.
551
559
  - The site: no change. It has no MCP host, and it used no function of `peer/security.ts`.
552
- - MiniMongo: no change. Its dev host has only the HTTP and WebSocket faces of `createProcedureHost()`. Each request of these faces had one check before.
553
- - Graph: its `mcpFace()` on the procedures host uses `graphPrincipalOf` for each HTTP request. In the accounts mode, a request without a session gets `ANONYMOUS`. Thus an MCP client without a session gets no 401 at `initialize`.
554
- - Graph: in the mode `on` (`AUTH_MODE=on`), a request without a tenant token gets 401 at `initialize`. Before, the client opened a session and listed the tools, and each tool call got `UNAUTHORIZED`.
555
- - Graph: accounts that are not ready (the error `UNAVAILABLE` of the hook) give 401 at `initialize`, with `WWW-Authenticate: Bearer`. Before, `initialize` passed, and each tool call got `UNAUTHORIZED`. An MCP client can start its OAuth discovery on this 401.
556
- - Graph: outside the accounts mode, the policy has `allowedOrigins: "*"`. The MCP face takes it, as the HTTP face does. A request with a cookie still needs a named origin. With the default `ambientCredentials: "always"` of its request hook, `"*"` permits no other origin.
557
- - Graph: to keep only the own origin on the MCP face, give `mcpFace({ allowedOrigins: [] })`. Its MCP host over stdio has no change.
558
- - jarvis: no change. Its procedures host has only the HTTP face, and its MCP host has only stdio and SDK faces.
560
+ - An app: no change. Its dev host has only the HTTP and WebSocket faces of `createProcedureHost()`. Each request of these faces had one check before.
561
+ - An app: its `mcpFace()` on the procedures host uses a session hook for each HTTP request. In the accounts mode, a request without a session gets `ANONYMOUS`. Thus an MCP client without a session gets no 401 at `initialize`.
562
+ - An app: in the mode `on` (`AUTH_MODE=on`), a request without a tenant token gets 401 at `initialize`. Before, the client opened a session and listed the tools, and each tool call got `UNAUTHORIZED`.
563
+ - An app: accounts that are not ready (the error `UNAVAILABLE` of the hook) give 401 at `initialize`, with `WWW-Authenticate: Bearer`. Before, `initialize` passed, and each tool call got `UNAUTHORIZED`. An MCP client can start its OAuth discovery on this 401.
564
+ - An app: outside the accounts mode, the policy has `allowedOrigins: "*"`. The MCP face takes it, as the HTTP face does. A request with a cookie still needs a named origin. With the default `ambientCredentials: "always"` of its request hook, `"*"` permits no other origin.
565
+ - An app: to keep only the own origin on the MCP face, give `mcpFace({ allowedOrigins: [] })`. Its MCP host over stdio has no change.
566
+ - An app: no change. Its procedures host has only the HTTP face, and its MCP host has only stdio and SDK faces.
559
567
  - `mark mcp --http --token` and `@procedures/mcp-dev-tools`: no change for a client. The token is the token of the server, and the server checks each HTTP request one time.
560
568
 
561
569
  ## 0.26.2
@@ -643,9 +651,9 @@ No changes in this release.
643
651
  - A test that expects `retryable: false` for such an end before the first item: expect the flag of the code.
644
652
  - A custom `errorOf` of `writeNdjsonStream`: read its second parameter to give the same rule.
645
653
  - The site: no change is necessary. The lab simulates its server with explicit flags. The streams of the journey do not fail.
646
- - MiniMongo: no change is necessary. Its browser client has the retry middleware, but its procedures throw no `UNAVAILABLE`, `CONNECTION_CLOSED` or `RATE_LIMITED` without a flag.
647
- - Graph: no change is necessary. Its handlers give `UNAVAILABLE` with an explicit flag, and it serves no stream procedure of its own.
648
- - jarvis: no change is necessary. The cuts of its host have their own flag, and it uses no retry middleware.
654
+ - An app: no change is necessary. Its browser client has the retry middleware, but its procedures throw no `UNAVAILABLE`, `CONNECTION_CLOSED` or `RATE_LIMITED` without a flag.
655
+ - An app: no change is necessary. Its handlers give `UNAVAILABLE` with an explicit flag, and it serves no stream procedure of its own.
656
+ - An app: no change is necessary. The cuts of its host have their own flag, and it uses no retry middleware.
649
657
 
650
658
  ### Patch Changes
651
659
 
@@ -674,7 +682,7 @@ No changes in this release.
674
682
 
675
683
  `WIRE-PROTOCOL.md` (section "Error codes") and the doc comments of `errorResponse`, `defaultNdjsonError`, `errorStatus` and `streamErrorMeta` have the deprecation notes.
676
684
 
677
- The site, MiniMongo, Graph and jarvis: no change in this release.
685
+ Apps: no change in this release.
678
686
 
679
687
  ## 0.24.0
680
688
 
@@ -705,9 +713,9 @@ No changes in this release.
705
713
 
706
714
  Migration:
707
715
 
708
- - The site and MiniMongo: no change. They have no MCP host.
709
- - Graph: no change. Its MCP hosts have no task store.
710
- - jarvis: no change. Its MCP host has no tasks.
716
+ - The site and an app: no change. They have no MCP host.
717
+ - An app: no change. Its MCP hosts have no task store.
718
+ - An app: no change. Its MCP host has no tasks.
711
719
  - polite-crawler-mcp: no change. Each request has the host token, so each session is one client. A session with 100 tasks gets fewer tasks only when ten or more sessions are near the limit. To keep the rule of CLI-51, give `new McpTaskStore({ reserve: 0 })`.
712
720
  - A host whose clients each have many sessions under one principal: each client keeps at most `maxStored - reserve` tasks. To keep the rule of CLI-51, give `reserve: 0` in `tasks` of the host or in `new McpTaskStore()`.
713
721
  - 71091a5: Added: the envelope form of a program (coeval, decisions D6, D9 and D10, roadmap item M7). A call is `{ "type": ["client", "add"], "value": input }`, and a reference is `{ "type": "ref", "value": ["names", "sum"] }`. The `$proc` form does not change.
@@ -737,9 +745,9 @@ No changes in this release.
737
745
 
738
746
  - Does a subscriber of `a.b` get `FORBIDDEN` with the reason `partition-not-allowed`? Then make the resolver of `a.b` give a partition. Or rename `a.b` to a name without a dot, for example `a_b`.
739
747
  - The site: no change is necessary. It serves no collection.
740
- - MiniMongo: no change is necessary. Its server serves no collection.
741
- - Graph: no change is necessary. Its one served collection, `examples`, has no dot in its name.
742
- - jarvis: no change is necessary. Its host serves no collection.
748
+ - An app: no change is necessary. Its server serves no collection.
749
+ - An app: no change is necessary. Its one served collection, `examples`, has no dot in its name.
750
+ - An app: no change is necessary. Its host serves no collection.
743
751
 
744
752
  ## 0.22.0
745
753
 
@@ -774,9 +782,9 @@ No changes in this release.
774
782
  The migration steps of the known consumers:
775
783
 
776
784
  - The site: no change. It imports none of these names. It names `HttpServerTransport` and `WebSocketServerTransport` only in the text of its journey.
777
- - MiniMongo: no change. It imports none of these names, and its host uses `runProcedureHost`. Its `vite.config.ts` maps the root to `@procedures/client/browser`. The map can stay, because the root is also a browser entry.
778
- - Graph: no change. It imports none of these names.
779
- - jarvis: no change. It imports none of these names.
785
+ - An app: no change. It imports none of these names, and its host uses `runProcedureHost`. Its `vite.config.ts` maps the root to `@procedures/client/browser`. The map can stay, because the root is also a browser entry.
786
+ - An app: no change. It imports none of these names.
787
+ - An app: no change. It imports none of these names.
780
788
  - The procedures image of the harness of `systems` (`packages/harness/image/procedures/server-ws.mjs`) imports `WebSocketServerTransport` from the root. It pins `@procedures/client` 0.7.0. When it moves to this MINOR or a later version, import `WebSocketServerTransport` from `@procedures/client/node`.
781
789
  - `headroom` (`packages/daemon/src/gateway.ts`) gives `checkBrowserRequest` of the root a request of `node:http`: no change.
782
790
 
@@ -805,9 +813,9 @@ No changes in this release.
805
813
  - A custom transport or face that sends no credentials to a server with a token or a request hook now gets `UNAUTHORIZED`. Set the credentials of its request (`requestCredentials()`), or `LOCAL_CREDENTIALS` for a face in this process.
806
814
  - Code that calls `server.handle()` of a server with a token or a request hook gives `credentials: LOCAL_CREDENTIALS`.
807
815
  - The site: no change. Its servers have no token and no request hook, and its workers serve over `PortTransport`, which sets the marker.
808
- - MiniMongo: no change. `scripts/dev.ts` starts a server without a token and without a request hook. Its HTTP and WebSocket faces set the credentials of each request.
809
- - Graph: no change. The procedure host (`packages/server/graph-host.ts`) has a request hook (`graphPrincipalOf` of `packages/server/graph-procedures.ts`) and no token. All its faces send credentials: HTTP, WebSocket and MCP over Streamable HTTP (`mcpFace`). No code of Graph calls `handle()` directly. The MCP host (`packages/mcp/src/host.ts`) operates over stdio, which is local.
810
- - jarvis: no change. The loopback server and the remote server of `packages/http/src/procedures.ts` have a request hook (`principalOf`), and the remote server has a token. `makeProcedureHandler` mounts `procedureHandler`, which sends the credentials of each request. A test that calls `handle()` of such a server gives `LOCAL_CREDENTIALS`, or credentials with the token.
816
+ - An app: no change. `scripts/dev.ts` starts a server without a token and without a request hook. Its HTTP and WebSocket faces set the credentials of each request.
817
+ - An app: no change. Its procedure host has a request hook and no token. All its faces send credentials: HTTP, WebSocket and MCP over Streamable HTTP (`mcpFace`). No code of the app calls `handle()` directly. Its MCP host operates over stdio, which is local.
818
+ - An app: no change. Its loopback server and its remote server have a request hook (`principalOf`), and the remote server has a token. `makeProcedureHandler` mounts `procedureHandler`, which sends the credentials of each request. A test that calls `handle()` of such a server gives `LOCAL_CREDENTIALS`, or credentials with the token.
811
819
 
812
820
  ## 0.18.1
813
821
 
@@ -827,9 +835,9 @@ No changes in this release.
827
835
 
828
836
  - When a host fails with `CollectionTopicCollisionError`, rename the plain collection, for example `a.b` to `a_b`. A name without a dot has no topic of a partition.
829
837
  - The site: no change is necessary. It serves no collection.
830
- - MiniMongo: no change is necessary. Its server serves no collection.
831
- - Graph: no change is necessary. Its host gives partitions to each served collection (`examples`), and no collection has a plain storage.
832
- - jarvis: no change is necessary. Its host serves no collection.
838
+ - An app: no change is necessary. Its server serves no collection.
839
+ - An app: no change is necessary. Its host gives partitions to each served collection (`examples`), and no collection has a plain storage.
840
+ - An app: no change is necessary. Its host serves no collection.
833
841
  - 0379278: Docs and tests: the rule of the retryable flag of an in-band end (CLI-58). The behavior does not change, thus this change is a PATCH of the client group (decision D13).
834
842
 
835
843
  - Before the stream starts, an error of a handler without a retryable flag gets the flag of its code in `ERROR_CODES` (CLI-48). Thus `UNAVAILABLE` without a flag is retryable, and the HTTP face answers 503.
@@ -840,7 +848,7 @@ No changes in this release.
840
848
  - This rule agrees with the rule of a cut (CLI-48): the flag is false when the call can have had its effect.
841
849
  - `WIRE-PROTOCOL.md` gives the rule in the section "Error codes". Tests pin it on the wire of HTTP and WebSocket, and on the HTTP, WebSocket and MCP faces of the procedures host.
842
850
 
843
- The site, MiniMongo, Graph and jarvis: no change.
851
+ Apps: no change.
844
852
 
845
853
  ## 0.18.0
846
854
 
@@ -882,9 +890,9 @@ No changes in this release.
882
890
  - Code that matches the status 405 or 415 of a procedure server: match the status 403 and the reasons `method-not-allowed` and `media-type-not-allowed`.
883
891
  - Code that reads `GuardResult.code` of `checkBrowserRequest()`: read `reason`.
884
892
  - Code that matches the code `"500"` or the default code of `ServerError`: match `INTERNAL_ERROR`.
885
- - The site, MiniMongo, Graph and jarvis: no code of theirs matches a former code, so no change is necessary.
886
- - MiniMongo: its dev server uses `HttpServerTransport`, and its answers change only as the table says.
887
- - jarvis: its host uses `procedureHandler`, which gave the codes of wire v1 already.
893
+ - Apps: no code of theirs matches a former code, so no change is necessary.
894
+ - An app: its dev server uses `HttpServerTransport`, and its answers change only as the table says.
895
+ - An app: its host uses `procedureHandler`, which gave the codes of wire v1 already.
888
896
 
889
897
  ## 0.17.4
890
898
 
@@ -945,9 +953,9 @@ No changes in this release.
945
953
  - For each collection with partitions whose name has `%` or `.`, upgrade the publishers and the subscribers together.
946
954
  - Build each topic rule of a collection with `collectionTopicRule()`. Do not join the parts yourself.
947
955
  - The site: no change is necessary. It has no collection with partitions.
948
- - MiniMongo: no change is necessary. It has no collection with partitions.
949
- - Graph: no change is necessary. Graph has dotted names of collections, but no dotted name has partitions yet. When a dotted name gets partitions, build the rule of `graph-host.ts` with `collectionTopicRule()`, not `collections.${c}.*`.
950
- - jarvis: no change is necessary. It has no collection with partitions.
956
+ - An app: no change is necessary. It has no collection with partitions.
957
+ - An app: no change is necessary. The app has dotted names of collections, but no dotted name has partitions yet. When a dotted name gets partitions, build the rule of its host with `collectionTopicRule()`, not `collections.${c}.*`.
958
+ - An app: no change is necessary. It has no collection with partitions.
951
959
 
952
960
  ## 0.15.1
953
961
 
@@ -977,7 +985,7 @@ No changes in this release.
977
985
  principalOf,
978
986
  limits: [
979
987
  {
980
- name: "graph.writes",
988
+ name: "app.writes",
981
989
  key: { claim: "tenant" },
982
990
  covers: { writes: true },
983
991
  policy: { type: "sliding-window", limit: { value: 120, unit: "count" }, window: { value: 1, unit: "min" } },
@@ -1037,9 +1045,9 @@ No changes in this release.
1037
1045
  Migration:
1038
1046
 
1039
1047
  - **Site.** No change. The site does not write collections.
1040
- - **MiniMongo.** No change for a storage or a `HybridStorage` without `versionOf`. A `HybridStorage` with `versionOf` over `ApiStorage` needs a server storage with the same `versionOf` (for example `new InMemoryStorage({ versionOf })`), or the option `sendBaseVersions: false`.
1041
- - **Graph.** Graph keeps last-write-wins first (D11): it gives no expected version, so nothing changes. `GraphDocsStorage` must refuse a write with an expected version until it tests one. Add the guard to its `set`, `delete` and `setBatch`, and run the contract suite: its first case tests the refusal. To adopt the version later, stamp a version field on the server, give the storage a `versionOf` that tests it in the write, and give the same `versionOf` to the `HybridStorage` of the client. Then add `createWithVersions` to the contract run.
1042
- - **jarvis.** No change: jarvis gives no expected version. A storage of jarvis that implements `CollectionStorage` must refuse a write with an expected version, as for Graph.
1048
+ - **An app with `HybridStorage`.** No change for a storage or a `HybridStorage` without `versionOf`. A `HybridStorage` with `versionOf` over `ApiStorage` needs a server storage with the same `versionOf` (for example `new InMemoryStorage({ versionOf })`), or the option `sendBaseVersions: false`.
1049
+ - **An app with last-write-wins.** It gives no expected version, so nothing changes. Its own storage must refuse a write with an expected version until it tests one. Add the guard to its `set`, `delete` and `setBatch`, and run the contract suite: its first case tests the refusal. To adopt the version later, stamp a version field on the server, give the storage a `versionOf` that tests it in the write, and give the same `versionOf` to the `HybridStorage` of the client. Then add `createWithVersions` to the contract run.
1050
+ - **An app without versions.** No change: it gives no expected version. A storage of the app that implements `CollectionStorage` must refuse a write with an expected version, as above.
1043
1051
  - **Other storages.** Each class that implements `CollectionStorage` reads the new options of `set`, `delete` and `setBatch`. It tests them in the write, or it rejects the write with `preconditionNotSupported()`. It never ignores them.
1044
1052
 
1045
1053
  ## 0.14.1
@@ -1073,9 +1081,9 @@ No changes in this release.
1073
1081
  The migration steps of the known consumers:
1074
1082
 
1075
1083
  - The site: no change. It imports none of these names.
1076
- - MiniMongo: no change. It imports none of these names. The server stub in `vite.config.ts` names `HttpServerTransport` and `WebSocketServerTransport`, and it can stay.
1077
- - Graph: no change. It imports none of these names.
1078
- - jarvis: no change. It imports none of these names.
1084
+ - An app: no change. It imports none of these names. The server stub in `vite.config.ts` names `HttpServerTransport` and `WebSocketServerTransport`, and it can stay.
1085
+ - An app: no change. It imports none of these names.
1086
+ - An app: no change. It imports none of these names.
1079
1087
  - The procedures image of the harness of `systems` (`packages/harness/image/procedures/server-ws.mjs`) imports `WebSocketServerTransport` from the root. It pins `@procedures/client` 0.7.0. When it moves to a version after the next MINOR, import `WebSocketServerTransport` from `@procedures/client/node`.
1080
1088
 
1081
1089
  ## 0.14.0
@@ -1108,16 +1116,16 @@ No changes in this release.
1108
1116
  - A caller that finds a cut by the code `INTERNAL_ERROR`: look for `UNAVAILABLE` in its place. Do not retry the call when `retryable` is false.
1109
1117
  - A handler that throws `UNAVAILABLE` with `retryable: false`: its HTTP status is 500 in place of 503. Without the flag, the error is retryable and gets 503. A retry middleware then sends the call again, so give `retryable: false` when the call can have had its effect.
1110
1118
  - The site: no change is necessary. Its code does not read the code of a cut, or the HTTP status 503.
1111
- - MiniMongo: no change is necessary. Its code does not read `INTERNAL_ERROR`, `UNAVAILABLE` or the severity of an error.
1112
- - The procedures host of Graph (GRAPH-11): no change is necessary. Its code does not read `INTERNAL_ERROR`. Its error "the server has no AGENT_TOKEN" is `UNAVAILABLE` with `retryable: false`, so its HTTP status is 500 in place of 503. No code of Graph reads that status.
1113
- - jarvis: no change is necessary. Its drain test already expects `UNAVAILABLE` with `retryable: false` for a cut procedure call (S6 A12). Its code reads only `NOT_FOUND` and `FORBIDDEN`.
1119
+ - An app: no change is necessary. Its code does not read `INTERNAL_ERROR`, `UNAVAILABLE` or the severity of an error.
1120
+ - The procedures host of an app (APP-11): no change is necessary. Its code does not read `INTERNAL_ERROR`. Its error "the server has no AGENT_TOKEN" is `UNAVAILABLE` with `retryable: false`, so its HTTP status is 500 in place of 503. No code of the app reads that status.
1121
+ - An app: no change is necessary. Its drain test already expects `UNAVAILABLE` with `retryable: false` for a cut procedure call (S6 A12). Its code reads only `NOT_FOUND` and `FORBIDDEN`.
1114
1122
  - The `mark` CLI and `procedure-server`: no change is necessary. The lifecycle test of CI-2 expects `UNAVAILABLE` for the cut of `lifecycle.ticksOnce`.
1115
1123
 
1116
1124
  ## 0.13.2
1117
1125
 
1118
1126
  ### Patch Changes
1119
1127
 
1120
- - 3a235b9: New: the patch operations `$remove` and `$insert` (Graph's split, wave 2, W5). `$remove` takes an element out of an array, and the next elements move down by one, as the operation `remove` of JSON Patch (RFC 6902). For a field of an object, it is the same as `$unset`. `$insert` adds an element to an array at an index, as the operation `add` of JSON Patch. Each index of one patch refers to the item before the patch. A patch that removes and inserts elements of the same array is refused, and so is an `$insert` past the end of an array. `$unset` keeps the rule of MongoDB: an element of an array becomes `null`. The storage contract has a case for the two operations, so each storage gets them through `applyPatch`.
1128
+ - 3a235b9: New: the patch operations `$remove` and `$insert`. `$remove` takes an element out of an array, and the next elements move down by one, as the operation `remove` of JSON Patch (RFC 6902). For a field of an object, it is the same as `$unset`. `$insert` adds an element to an array at an index, as the operation `add` of JSON Patch. Each index of one patch refers to the item before the patch. A patch that removes and inserts elements of the same array is refused, and so is an `$insert` past the end of an array. `$unset` keeps the rule of MongoDB: an element of an array becomes `null`. The storage contract has a case for the two operations, so each storage gets them through `applyPatch`.
1121
1129
 
1122
1130
  ## 0.13.1
1123
1131
 
@@ -1148,10 +1156,10 @@ No changes in this release.
1148
1156
  - A host with an `expose` rule must list the collection procedures that it serves, for example `collections.notes.*`. `host.*` and `events.subscribe` stay always on.
1149
1157
  - An app that pins its own procedures with `registerProcedures()` on a server with an expose rule: list them in the rule. Give `{ alwaysOn: true }` only to a procedure of the host itself.
1150
1158
  - The site: no change is necessary. Its servers have no expose rule.
1151
- - MiniMongo: no change is necessary. Its server has an expose rule, but it pins no procedure and serves no collection.
1159
+ - An app: no change is necessary. Its server has an expose rule, but it pins no procedure and serves no collection.
1152
1160
  - The `mark` CLI and `procedure-server`: no change is necessary. They serve no collection, and `--expose` keeps `host.*` and `events.subscribe` on.
1153
- - jarvis: no change is necessary. Its host has no expose rule.
1154
- - The procedures host of Graph (GRAPH-11): no change is necessary. Its rule `["collections.*", "graph.*"]` lists the collection procedures. To hide `clear`, an `exclude` of the policy now has an effect.
1161
+ - An app: no change is necessary. Its host has no expose rule.
1162
+ - The procedures host of an app (APP-11): no change is necessary. Its rule `["collections.*", "app.*"]` lists the collection procedures. To hide `clear`, an `exclude` of the policy now has an effect.
1155
1163
 
1156
1164
  ## 0.12.2
1157
1165
 
@@ -1200,9 +1208,9 @@ No changes in this release.
1200
1208
 
1201
1209
  Migration steps:
1202
1210
 
1203
- - The site and MiniMongo: no change is necessary, unless they read `/health` of a peer. Then call `host.info` with the token.
1204
- - The MCP host of Graph: no change is necessary. To share the port of the Graph host, mount `mcpFace()` on its listener.
1205
- - jarvis and Graph under `run()`: build the procedures with `createProcedureHost()`, and call `host.declare(svc)` in the service of the process. Give `listen` for a port of the host, or mount `host.handler` and `host.upgrade` on the listener of the app.
1211
+ - The site and an app: no change is necessary, unless they read `/health` of a peer. Then call `host.info` with the token.
1212
+ - The MCP host of an app: no change is necessary. To share the port of its procedures host, mount `mcpFace()` on its listener.
1213
+ - Apps under `run()`: build the procedures with `createProcedureHost()`, and call `host.declare(svc)` in the service of the process. Give `listen` for a port of the host, or mount `host.handler` and `host.upgrade` on the listener of the app.
1206
1214
  - A caller of `createPeer()` with a different token for each transport: give one token.
1207
1215
  - A Docker `HEALTHCHECK` or a probe of Kubernetes that read `/health` of a peer: use the probes of the service. Give the service `probeServer({ port, server_retry_after })` on a port of its own, or mount `probeHandler(health, { prefix: "/health" })` on the port of the app. Both come from `@mark1russell7/service/http`, and they answer `/health/startup`, `/health/readiness` and `/health/liveness`. The lockfile check of a client calls `host.info` with the token of the lockfile.
1208
1216
  - A test that read `/health` of a peer: call `host.info` with the token, or check the status 404.
@@ -1230,8 +1238,8 @@ No changes in this release.
1230
1238
 
1231
1239
  Migration steps:
1232
1240
 
1233
- - The site, MiniMongo and the MCP host of Graph: no change is necessary. `stop({ grace })` keeps its result. Change `server.callsInFlight` to `server.inFlight()`.
1234
- - jarvis and Graph under `run()`: declare the parts in the service of the process. Do not call `stop()`. Declare `svc.server("procedures", {}, server)`, and declare each handle of `server.storageHandles()` with `svc.dependency(handle.name, spec, handle)`. Give the server and `run()` the same clock, with the option `clock` of each.
1241
+ - The site, an app and the MCP host of another app: no change is necessary. `stop({ grace })` keeps its result. Change `server.callsInFlight` to `server.inFlight()`.
1242
+ - Apps under `run()`: declare the parts in the service of the process. Do not call `stop()`. Declare `svc.server("procedures", {}, server)`, and declare each handle of `server.storageHandles()` with `svc.dependency(handle.name, spec, handle)`. Give the server and `run()` the same clock, with the option `clock` of each.
1235
1243
  - A test with a fake clock that calls `stop({ grace })` with calls in flight: advance the clock by the grace, or stop without a grace.
1236
1244
 
1237
1245
  ## 0.9.2
@@ -1344,14 +1352,14 @@ No changes in this release.
1344
1352
  - The option `origin` of `HybridStorage` is the tag of the storage (a random `hybrid-…` tag by default). Each write of the storage to the local copy and to the remote has it. The write methods of `HybridStorage` and `ApiStorage` take `{ origin }`.
1345
1353
  - `capture: "observe"`: the storage observes the local copy and queues each change with another origin. Thus an application can write to the local copy directly, for example with the synchronous writes of a SignalDB collection. In `write-through` and `remote-only` mode, the storage sends a captured change at once.
1346
1354
  - The option `syncState` takes a `SyncStateStore`: `MemorySyncStateStore`, or `IndexedDbSyncStateStore` of `@procedures/store/indexeddb`. The store keeps the cursor and the base versions. A new storage with the same store and a durable local copy asks only for the changes since the cursor, and it finds the conflicts of the base versions. A failure of the store goes to the status (`operation: "store"`, `SyncStateError`), and the storage goes on.
1347
- - The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it (the LiveLog rule of Graph).
1355
+ - The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it.
1348
1356
  - In `write-through` mode, a pull or a delta does not write over an own write that waits for the remote, a set or a delete. The storage keeps the remote value of the id, and after the write it reads the id again: then the rules of a pull decide. A read of a missing id does not bring back an item whose own delete waits.
1349
- - With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write (the EchoLedger rule of Graph).
1357
+ - With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write.
1350
1358
  - `EventsChangeFeed` of `@procedures/store` is the feed of the change events. Its source is a `Client`, a `WebSocketTransport` or another transport. It treats the events as hints: a gap of the numbers, a lost event, a hint and each confirmation of the subscription call `onGap()`.
1351
1359
  - The core collection procedures publish `CollectionChangeEvent` `{ since, version, changed, deleted, origin }` on `ctx.bus`, under the topic `collections.<name>` (`collectionChangeTopic()`), while a subscriber listens. The changes come from `getChangesSince()` of the storage, and the events of one storage make a chain of versions. The option `changeEvents` of `createCollectionProcedures()` turns them off, or gives the topic of each call: the partition of CLI-17 goes there.
1352
1360
  - A value reaches a subscriber only through the checks of a read. By default, an event has the ids and the versions only, and `EventsChangeFeed` gives it to `onHint()`: `HybridStorage` reads the values with `changes`, and a hint with only deletes applies without a read. With `changeEvents: { values: true }`, an event also has `values`: each row `{ id, value }` passes the output filter of the host (`admitItem`) for each subscriber, and a refused id goes in `withheld`, so the storage pulls it.
1353
1361
  - `EventPublisher` refuses a topic whose reads the capability of the call does not permit (`FORBIDDEN`, `effects-exceeded`). Its new option `reads` gives the reads of a topic. The default, `collectionTopicReads()`, gives `collection:<name>` for `collections.<name>` and `collections.<name>.<partition>`. `ctx.admit` gives a procedure the output filter of its host for the data that it sends later.
1354
- - The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time (Graph R18).
1362
+ - The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time.
1355
1363
  - The write inputs of the collection procedures take an optional `origin` (1 to 256 characters). The procedure gives it to the storage and to the event. A server before this change ignores the field.
1356
1364
  - `Client.subscribe()` and `Client.events()` subscribe to the topics of the bus of the server through the middleware and the context of the client. A subscription has no deadline: the timeouts of the client do not apply to it, and only `metadata: { timeout }` in its options gives one.
1357
1365
  - New exports: `collectionChangeTopic`, `CollectionChangeEvent` and `CollectionChangeEventsOptions` from `@procedures/client`, `./browser` and `./procedures`. `EventsChangeFeed`, `MemorySyncStateStore`, `SyncStateError` and the types `RemoteChangeFeed`, `RemoteChangeListener`, `RemoteChanges`, `EventSubscriber`, `ChangeEventSource`, `EventsChangeFeedOptions`, `SyncState`, `SyncStateChange` and `SyncStateStore` from `@procedures/store`. `IndexedDbSyncStateStore` and `MemorySyncStateStore` from `@procedures/store/indexeddb`.
@@ -1420,7 +1428,7 @@ No changes in this release.
1420
1428
 
1421
1429
  ### Patch Changes
1422
1430
 
1423
- - 389b054: A token check no longer tells the length of the token through its time. The peer compares the SHA-256 digests of the two tokens with `timingSafeEqual`. The `tokenMatches` of the client, which runs in a browser too, compares each character of the expected token for each presented token. Before, a token of another length returned at once. The re-audit of jarvis found it.
1431
+ - 389b054: A token check no longer tells the length of the token through its time. The peer compares the SHA-256 digests of the two tokens with `timingSafeEqual`. The `tokenMatches` of the client, which runs in a browser too, compares each character of the expected token for each presented token. Before, a token of another length returned at once. A re-audit found it.
1424
1432
 
1425
1433
  ## 0.6.0
1426
1434
 
package/README.md CHANGED
@@ -693,7 +693,7 @@ http.listen(4820);
693
693
  - An `OPTIONS` request gets 204 and starts no procedure.
694
694
  - `cors: { origin: ["https://app.example"], credentials: true }` lets a page of that origin call with its cookies. A list or a function of origins sends `Access-Control-Allow-Credentials: true` by default.
695
695
  - An origin that the CORS does not permit gets no `Access-Control-*` header. With a list or a function of origins, each response gets `Vary: Origin`.
696
- - `secretHeaders` names more headers that carry a secret, for example `X-Jarvis-Token`. `secretQuery` names the query parameters that carry a secret. Its default is `["token"]`. These values go into the credentials of the request, not into its metadata.
696
+ - `secretHeaders` names more headers that carry a secret, for example `X-App-Token`. `secretQuery` names the query parameters that carry a secret. Its default is `["token"]`. These values go into the credentials of the request, not into its metadata.
697
697
  - `handler.middleware` mounts the handler in Connect or Express. A request outside `basePath` goes to `next`.
698
698
  - The handler has the stop parts of a service transport: `start()`, `stopIntake()`, `drain(deadline, signal)`, `inFlight()` and `close()`. It does not make a server and does not listen.
699
699
 
@@ -743,9 +743,9 @@ const server = new ProcedureServer({
743
743
  capability: { clearance: "intimate" },
744
744
  principalOf: ({ cookies = {}, headers = {}, query = {} }) => ({
745
745
  // The token of a cookie, of an application header or of the query
746
- bearer: cookies["jarvis_token"] ?? headers["x-jarvis-token"] ?? query["token"],
746
+ bearer: cookies["app_token"] ?? headers["x-app-token"] ?? query["token"],
747
747
  // A guest switch can only make the capability narrower
748
- ...(cookies["jarvis_audience"] ? { narrowing: { clearance: cookies["jarvis_audience"] } } : {}),
748
+ ...(cookies["app_audience"] ? { narrowing: { clearance: cookies["app_audience"] } } : {}),
749
749
  }),
750
750
  });
751
751
  ```