@fleetless/contracts 1.0.4 → 1.0.5
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 +57 -1
- package/artifacts/openapi.json +2 -2
- package/artifacts/routes.json +2 -2
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +1 -1
- package/dist/config-issues.d.ts +2 -2
- package/dist/config-issues.js +2 -2
- package/dist/config.d.ts +1 -1
- package/dist/config.js +5 -5
- package/dist/errors.js +7 -7
- package/dist/identity.d.ts +2 -2
- package/dist/identity.js +2 -2
- package/dist/routes.js +4 -4
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,62 @@ follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the
|
|
|
5
5
|
project uses [semantic versioning](https://semver.org/spec/v2.0.0.html) over
|
|
6
6
|
the wire shapes.
|
|
7
7
|
|
|
8
|
+
## [1.0.5] — 2026-09-07
|
|
9
|
+
|
|
10
|
+
The guard was rebuilt around the set of bytes that become public rather than
|
|
11
|
+
around three directory names, and it found 190 things the old shape could not
|
|
12
|
+
see. **No wire shape changes**: two `notes` sentences are repaired and nothing
|
|
13
|
+
else in `artifacts/` moves.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Two sentences an earlier sweep broke, in the published API reference.**
|
|
18
|
+
`POST /mcp/:appIdentifier` ended "one answer for two states, which is one
|
|
19
|
+
answer for two states", a tautology left behind when a clause was removed;
|
|
20
|
+
`GET /api/robots/:id/jobs/history` read "`history` is a syntactically valid
|
|
21
|
+
slug and The router matches a static segment first", a mid-sentence capital
|
|
22
|
+
left behind when a product name was replaced. Both are in `routes.json` and
|
|
23
|
+
`openapi.json`, so both were in every client generated from 1.0.4 and on the
|
|
24
|
+
public reference page.
|
|
25
|
+
- **Six internal schedule references on exported schemas**, in `alerts.ts`,
|
|
26
|
+
`config.ts`, `config-issues.ts`, `errors.ts` and `identity.ts`. They ship in
|
|
27
|
+
the declarations, so an editor showed them on hover to anyone who installed
|
|
28
|
+
the package. A private repository path in an `errors.ts` comment went with
|
|
29
|
+
them.
|
|
30
|
+
- **`test/` and `scripts/` were outside the guard entirely**, and both mirror
|
|
31
|
+
in full. 160 further references swept: internal decision labels, schedule
|
|
32
|
+
labels, citations of two repositories that stay private and of the
|
|
33
|
+
maintainer-only files, the reference robot's name in two fixtures, and
|
|
34
|
+
internal task ids.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **The scanned set is computed, not named.** It is the union of what `npm
|
|
39
|
+
pack` reports, what `git ls-files` reports and a walk of every directory in
|
|
40
|
+
`files`. A file in none of the three is out of scope; a file in any of them
|
|
41
|
+
is scanned. The predecessor named `src`, `dist`, `artifacts` and five
|
|
42
|
+
markdown files, which left `package.json`, `.gitlab-ci.yml`, the tsconfigs
|
|
43
|
+
and both other trees unswept.
|
|
44
|
+
- **Only the German scan strips anything**, and only URLs and single-token code
|
|
45
|
+
spans. Stripping links and backticks before every class made the shipped
|
|
46
|
+
documents blind to an internal hostname inside a markdown link.
|
|
47
|
+
- **Eighteen detectors, each carrying its own fixtures.** Suffixed decision
|
|
48
|
+
labels (`D3a` never matched), bare review codenames, schedule labels in the
|
|
49
|
+
three spellings this codebase writes, dotfile and bare two-segment paths into
|
|
50
|
+
a sibling repository, task ids and CI pipeline numbers. A floor over the
|
|
51
|
+
count makes deleting a detector red.
|
|
52
|
+
- **`scripts/verify-pack.mjs`** now reads the *packed* manifest rather than the
|
|
53
|
+
one on disk, checks every dependency section rather than `dependencies`
|
|
54
|
+
alone, runs the marker detectors over that manifest, asserts each published
|
|
55
|
+
file declares exactly **one** SPDX identifier rather than reading its first
|
|
56
|
+
line, and verifies that every relative link in every shipped document
|
|
57
|
+
resolves inside the tarball.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- **`scripts/verify-commit-messages.mjs`**, wired into the verify job. A commit
|
|
62
|
+
message is public the moment it is pushed, and this history mirrors.
|
|
63
|
+
|
|
8
64
|
## [1.0.4] — 2026-09-07
|
|
9
65
|
|
|
10
66
|
Two things a grep over the published 1.0.3 tarball found that the guard was not
|
|
@@ -12,7 +68,7 @@ looking for. **No wire shape changes**; `artifacts/` is byte-identical to 1.0.3.
|
|
|
12
68
|
|
|
13
69
|
### Fixed
|
|
14
70
|
|
|
15
|
-
- **A published `dist/` comment cited
|
|
71
|
+
- **A published `dist/` comment cited a maintainer-only file** and two internal server
|
|
16
72
|
symbols by name. Rewritten to say what the rule is rather than where it is
|
|
17
73
|
written down.
|
|
18
74
|
- **The markdown this package ships was outside the guard.** `README.md`,
|
package/artifacts/openapi.json
CHANGED
|
@@ -3643,7 +3643,7 @@
|
|
|
3643
3643
|
}
|
|
3644
3644
|
}
|
|
3645
3645
|
},
|
|
3646
|
-
"description": "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions — the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance — so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* —
|
|
3646
|
+
"description": "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions — the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance — so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* — so an unregistered verb and an unknown app would answer identically. Registering the verb lets the endpoint say \"this app's server is here; this verb is not part of it\". The central `/mcp` registers neither verb and does not need to: its path takes no parameter, so nothing can misread its `404`. \n\n**The `405` body is the transport's JSON-RPC error object, not the `apiError` envelope.** The three codes above are the refusals that come *first* — the app, its switch, then the bearer, in the order `POST` describes — and they are `apiError` because they are answered before the transport is reached at all. If this server ever becomes stateful, this row and the `DELETE` beside it are where that lands, and the cloud's route-manifest test is what would make both repositories notice."
|
|
3647
3647
|
},
|
|
3648
3648
|
"delete": {
|
|
3649
3649
|
"operationId": "delete_mcp_appIdentifier",
|
|
@@ -6406,7 +6406,7 @@
|
|
|
6406
6406
|
}
|
|
6407
6407
|
}
|
|
6408
6408
|
},
|
|
6409
|
-
"description": "Needs the `action_history` capability, and **this route is what makes that switch mean something** — it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug and
|
|
6409
|
+
"description": "Needs the `action_history` capability, and **this route is what makes that switch mean something** — it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug, and a static segment matches before a parameter, so a robot with a service literally slugged `history` can no longer be **read** through `GET /api/robots/:id/jobs/:slug`; invoking, cancelling and the listing are unaffected. And a run row names its actor by email address, so an end user holding this capability learns which other people have been driving the machine. `robot_id` in the query is shared with the org-wide read; a *different* one here is refused rather than quietly answered about the robot in the path."
|
|
6410
6410
|
}
|
|
6411
6411
|
},
|
|
6412
6412
|
"/api/robots/{id}/jobs/{slug}": {
|
package/artifacts/routes.json
CHANGED
|
@@ -2370,7 +2370,7 @@
|
|
|
2370
2370
|
"forbidden"
|
|
2371
2371
|
],
|
|
2372
2372
|
"transport": "http",
|
|
2373
|
-
"notes": "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions — the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance — so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* —
|
|
2373
|
+
"notes": "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions — the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance — so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* — so an unregistered verb and an unknown app would answer identically. Registering the verb lets the endpoint say \"this app's server is here; this verb is not part of it\". The central `/mcp` registers neither verb and does not need to: its path takes no parameter, so nothing can misread its `404`. \n\n**The `405` body is the transport's JSON-RPC error object, not the `apiError` envelope.** The three codes above are the refusals that come *first* — the app, its switch, then the bearer, in the order `POST` describes — and they are `apiError` because they are answered before the transport is reached at all. If this server ever becomes stateful, this row and the `DELETE` beside it are where that lands, and the cloud's route-manifest test is what would make both repositories notice."
|
|
2374
2374
|
},
|
|
2375
2375
|
{
|
|
2376
2376
|
"method": "DELETE",
|
|
@@ -3788,7 +3788,7 @@
|
|
|
3788
3788
|
"validation_error"
|
|
3789
3789
|
],
|
|
3790
3790
|
"transport": "http",
|
|
3791
|
-
"notes": "Needs the `action_history` capability, and **this route is what makes that switch mean something** — it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug and
|
|
3791
|
+
"notes": "Needs the `action_history` capability, and **this route is what makes that switch mean something** — it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug, and a static segment matches before a parameter, so a robot with a service literally slugged `history` can no longer be **read** through `GET /api/robots/:id/jobs/:slug`; invoking, cancelling and the listing are unaffected. And a run row names its actor by email address, so an end user holding this capability learns which other people have been driving the machine. `robot_id` in the query is shared with the org-wide read; a *different* one here is refused rather than quietly answered about the robot in the path."
|
|
3792
3792
|
},
|
|
3793
3793
|
{
|
|
3794
3794
|
"method": "POST",
|
package/dist/alerts.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ import { z } from 'zod';
|
|
|
53
53
|
* derives it from the document (`alert-definitions.ts`'s `toRowCondition`) and
|
|
54
54
|
* derives it nowhere else.
|
|
55
55
|
*
|
|
56
|
-
* **It was renamed for a
|
|
56
|
+
* **It was renamed for a deletion that did not happen**, and the name
|
|
57
57
|
* is kept because the distinction it draws is still needed: two condition
|
|
58
58
|
* shapes coexist, and only one of them is authored. Nothing is stored under
|
|
59
59
|
* this shape any more — the database keeps runtime state only — so read `Row`
|
package/dist/alerts.js
CHANGED
|
@@ -54,7 +54,7 @@ import { slug } from './common.js';
|
|
|
54
54
|
* derives it from the document (`alert-definitions.ts`'s `toRowCondition`) and
|
|
55
55
|
* derives it nowhere else.
|
|
56
56
|
*
|
|
57
|
-
* **It was renamed for a
|
|
57
|
+
* **It was renamed for a deletion that did not happen**, and the name
|
|
58
58
|
* is kept because the distinction it draws is still needed: two condition
|
|
59
59
|
* shapes coexist, and only one of them is authored. Nothing is stored under
|
|
60
60
|
* this shape any more — the database keeps runtime state only — so read `Row`
|
package/dist/config-issues.d.ts
CHANGED
|
@@ -150,8 +150,8 @@ export declare function splitFormatPath(path: string): Array<string | number>;
|
|
|
150
150
|
* A stable hash of a schema object, for asking *is the thing running the one
|
|
151
151
|
* I think it is?*
|
|
152
152
|
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
153
|
+
* A browser sweep enumerates positions against a schema it holds and has to
|
|
154
|
+
* know that the editor is running the same one; the manifest that
|
|
155
155
|
* makes a schema-side change announce itself uses the same number as its
|
|
156
156
|
* baseline. Both are the same question, so there is one implementation of it:
|
|
157
157
|
* a second one on the sweep side would drift, and the gate would then go red
|
package/dist/config-issues.js
CHANGED
|
@@ -293,8 +293,8 @@ function valueAt(root, path) {
|
|
|
293
293
|
* A stable hash of a schema object, for asking *is the thing running the one
|
|
294
294
|
* I think it is?*
|
|
295
295
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
296
|
+
* A browser sweep enumerates positions against a schema it holds and has to
|
|
297
|
+
* know that the editor is running the same one; the manifest that
|
|
298
298
|
* makes a schema-side change announce itself uses the same number as its
|
|
299
299
|
* baseline. Both are the same question, so there is one implementation of it:
|
|
300
300
|
* a second one on the sweep side would drift, and the gate would then go red
|
package/dist/config.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ export type ParameterType = z.infer<typeof parameterType>;
|
|
|
74
74
|
*
|
|
75
75
|
* There is no `required` field. A placeholder cannot be left unfilled, so
|
|
76
76
|
* "required" is exactly "has no `default`" — a second spelling of one fact
|
|
77
|
-
* is the defect this file has
|
|
77
|
+
* is the defect this file has been removing a spelling at a time.
|
|
78
78
|
*/
|
|
79
79
|
export declare const parameterSpec: z.ZodObject<{
|
|
80
80
|
type: z.ZodEnum<{
|
package/dist/config.js
CHANGED
|
@@ -5,8 +5,8 @@ import { applyError, slug, rosName, rosTypeName, fieldPath, SLUG_RULE, ROS_NAME_
|
|
|
5
5
|
* `alertSeverity` is identical for the stored row and this document-nested
|
|
6
6
|
* definition — `z.enum(['warning', 'error'])`, nothing more to say twice —
|
|
7
7
|
* so it is imported rather than redefined. Not re-exported from here: the
|
|
8
|
-
* barrel already carries it from `alerts.ts`, and
|
|
9
|
-
*
|
|
8
|
+
* barrel already carries it from `alerts.ts`, and the definition itself moves
|
|
9
|
+
* into this file once `alerts.ts` retires.
|
|
10
10
|
*/
|
|
11
11
|
import { alertSeverity } from './alerts.js';
|
|
12
12
|
/**
|
|
@@ -97,8 +97,8 @@ import { alertSeverity } from './alerts.js';
|
|
|
97
97
|
* says. They are the same sentence, which is the point of there being one.
|
|
98
98
|
*
|
|
99
99
|
* The tense matters because the two states look identical from inside this
|
|
100
|
-
* file. Whoever reads it
|
|
101
|
-
*
|
|
100
|
+
* file. Whoever reads it later should find a claim that was true when written
|
|
101
|
+
* and stayed true, not one that quietly became false.
|
|
102
102
|
*
|
|
103
103
|
* Each one states the rule in words and gives one example, and none of them
|
|
104
104
|
* quotes its own regex — `config-messages.test.ts` asserts that over every
|
|
@@ -474,7 +474,7 @@ const PARAMETER_SNIPPET = {
|
|
|
474
474
|
*
|
|
475
475
|
* There is no `required` field. A placeholder cannot be left unfilled, so
|
|
476
476
|
* "required" is exactly "has no `default`" — a second spelling of one fact
|
|
477
|
-
* is the defect this file has
|
|
477
|
+
* is the defect this file has been removing a spelling at a time.
|
|
478
478
|
*/
|
|
479
479
|
export const parameterSpec = strictObject({
|
|
480
480
|
type: parameterType.meta({
|
package/dist/errors.js
CHANGED
|
@@ -420,14 +420,14 @@ export const ERROR_CODES = [
|
|
|
420
420
|
* no producer is not harmless, because a reader arriving at it takes it for
|
|
421
421
|
* a live refusal. Say which it is, and say when it changes.
|
|
422
422
|
*
|
|
423
|
-
* **It has one producer already,
|
|
424
|
-
* an `mcp_session` token whose subject is an app user,
|
|
425
|
-
* endpoint serves the team only. No client can hold such
|
|
426
|
-
* a test mints one — and the
|
|
427
|
-
*
|
|
423
|
+
* **It has one producer already, ahead of the gate it describes**: `POST
|
|
424
|
+
* /mcp` answers it to an `mcp_session` token whose subject is an app user,
|
|
425
|
+
* because the central endpoint serves the team only. No client can hold such
|
|
426
|
+
* a token yet — only a test mints one — and the `appAuthConfig.mcp_enabled`
|
|
427
|
+
* gate arrives with the per-app endpoint.
|
|
428
428
|
*
|
|
429
429
|
* `tool_not_available` below still has no producer — `grep` finds it nowhere
|
|
430
|
-
* in
|
|
430
|
+
* in the cloud's source. Named as unproduced, for the same reason.
|
|
431
431
|
*/
|
|
432
432
|
'mcp_disabled',
|
|
433
433
|
/**
|
|
@@ -536,7 +536,7 @@ export const ERROR_CODES = [
|
|
|
536
536
|
// what the cloud actually sends.
|
|
537
537
|
//
|
|
538
538
|
// They are listed in one block, with their producer named, rather than filed
|
|
539
|
-
//
|
|
539
|
+
// by the release that introduced each — the honest record is *when this list
|
|
540
540
|
// learned about them*, not when the cloud started sending them.
|
|
541
541
|
/**
|
|
542
542
|
* `409` from the configuration routes: the draft parses as YAML but its root
|
package/dist/identity.d.ts
CHANGED
|
@@ -502,8 +502,8 @@ export type IdpIssuer = z.infer<typeof idpIssuer>;
|
|
|
502
502
|
* The per-app OIDC vocabulary is `clientOidcErrorCode` in `client-auth.ts`: a
|
|
503
503
|
* different list, for a different flow, redirected to the developer's own page
|
|
504
504
|
* rather than rendered by Fleetless. Two callback error enums coexisting is how
|
|
505
|
-
* the wrong one gets picked up
|
|
506
|
-
*
|
|
505
|
+
* the wrong one gets picked up when per-app OIDC arrives, which is why this
|
|
506
|
+
* one is deleted rather than left standing for it.
|
|
507
507
|
*/
|
|
508
508
|
/**
|
|
509
509
|
* `GET /api/auth/me` — named so the console can validate it.
|
package/dist/identity.js
CHANGED
|
@@ -479,8 +479,8 @@ export const idpIssuer = z
|
|
|
479
479
|
* The per-app OIDC vocabulary is `clientOidcErrorCode` in `client-auth.ts`: a
|
|
480
480
|
* different list, for a different flow, redirected to the developer's own page
|
|
481
481
|
* rather than rendered by Fleetless. Two callback error enums coexisting is how
|
|
482
|
-
* the wrong one gets picked up
|
|
483
|
-
*
|
|
482
|
+
* the wrong one gets picked up when per-app OIDC arrives, which is why this
|
|
483
|
+
* one is deleted rather than left standing for it.
|
|
484
484
|
*/
|
|
485
485
|
/**
|
|
486
486
|
* `GET /api/auth/me` — named so the console can validate it.
|
package/dist/routes.js
CHANGED
|
@@ -1175,8 +1175,8 @@ export const ROUTES = [
|
|
|
1175
1175
|
'\n\n**The `405` is this cloud\'s own answer, not the SDK\'s**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on ' +
|
|
1176
1176
|
'`GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any ' +
|
|
1177
1177
|
'business doing, so the cloud writes the `405` itself in the transport\'s own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers ' +
|
|
1178
|
-
'`404`, and at a path whose last segment is an app identifier a `404` already means *no such app* —
|
|
1179
|
-
'
|
|
1178
|
+
'`404`, and at a path whose last segment is an app identifier a `404` already means *no such app* — so an unregistered verb and an ' +
|
|
1179
|
+
'unknown app would answer identically. Registering the verb lets the endpoint say "this app\'s server is here; this verb is not ' +
|
|
1180
1180
|
'part of it". The central `/mcp` registers neither verb and does not need to: its path takes no parameter, so nothing can misread its ' +
|
|
1181
1181
|
'`404`. \n\n**The `405` body is the transport\'s JSON-RPC error object, not the `apiError` envelope.** The three codes above are the ' +
|
|
1182
1182
|
'refusals that come *first* — the app, its switch, then the bearer, in the order `POST` describes — and they are `apiError` because ' +
|
|
@@ -1934,8 +1934,8 @@ export const ROUTES = [
|
|
|
1934
1934
|
query: jobRunQuery, request: null, response: jobRunListResponse,
|
|
1935
1935
|
errors: [...CLIENT_GUARD, 'invalid_uuid', 'not_found', 'capability_required', 'validation_error'], transport: 'http',
|
|
1936
1936
|
notes: 'Needs the `action_history` capability, and **this route is what makes that switch mean something** — it was unkeepable while nothing ' +
|
|
1937
|
-
'durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug and ' +
|
|
1938
|
-
'
|
|
1937
|
+
'durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug, and ' +
|
|
1938
|
+
'a static segment matches before a parameter, so a robot with a service literally slugged `history` can no longer be **read** through ' +
|
|
1939
1939
|
'`GET /api/robots/:id/jobs/:slug`; invoking, cancelling and the listing are unaffected. And a run row names its actor by email address, ' +
|
|
1940
1940
|
'so an end user holding this capability learns which other people have been driving the machine. `robot_id` in the query is shared with ' +
|
|
1941
1941
|
'the org-wide read; a *different* one here is refused rather than quietly answered about the robot in the path.',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetless/contracts",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Fleetless wire contracts: the bridge-cloud protocol, the REST API schemas and the error codes, as zod schemas with generated JSON Schema and OpenAPI artifacts.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dehne Robotik GmbH",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"test": "vitest run",
|
|
53
53
|
"artifacts": "tsx scripts/export-schemas.ts",
|
|
54
54
|
"test:pack": "node scripts/verify-pack.mjs",
|
|
55
|
+
"verify:commits": "node scripts/verify-commit-messages.mjs",
|
|
55
56
|
"prepublishOnly": "node scripts/refuse-manual-publish.mjs"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|