@worker-protocol/conformance 0.1.0 → 0.1.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/README.md +136 -0
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# @worker-protocol/conformance
|
|
2
|
+
|
|
3
|
+
Point it at a Worker's base URL, get a report of what it complies with.
|
|
4
|
+
|
|
5
|
+
**worker-protocol is an open specification for Workers that can be seen, operated and given work by
|
|
6
|
+
people who did not build them.** HTTP and JSON Schema, no runtime. A *Worker* describes itself in a
|
|
7
|
+
Descriptor served at `/.well-known/worker-protocol` — the one address this protocol fixes — and
|
|
8
|
+
declares there which of its Capabilities it implements.
|
|
9
|
+
|
|
10
|
+
This is the tool that checks whether it does what it says. It is also how the name is earned: the
|
|
11
|
+
protocol is Apache-2.0, but a claim that something *speaks worker-protocol* is one this project
|
|
12
|
+
vouches for, and a report from here is what stands behind it.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
npx @worker-protocol/conformance https://fleet.example.com
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
worker-protocol-conformance <base-url> [options]
|
|
22
|
+
|
|
23
|
+
--credential <token> Presented as `Authorization: Bearer <token>`.
|
|
24
|
+
Prefer WORKER_PROTOCOL_CREDENTIAL: argv is visible to
|
|
25
|
+
every process on the machine, and a CI log often keeps it.
|
|
26
|
+
--may-perform Allow POSTs to Actions. Off by default: an Action is an
|
|
27
|
+
operation somebody's operators chose to expose, and a tool
|
|
28
|
+
pointed at a Worker to inspect it does not perform work on
|
|
29
|
+
it uninvited. Rules needing one report notExercised.
|
|
30
|
+
--json Write the report to stdout as JSON, and nothing else.
|
|
31
|
+
-h, --help This.
|
|
32
|
+
|
|
33
|
+
Exit: 0 nothing failed, 1 a rule failed, 2 the run could not be made.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Everything but `actions` is a read, and a read leaves the Worker as it found it. That is why
|
|
37
|
+
`--may-perform` is a decision you make rather than a default: the rules that need a POST report
|
|
38
|
+
`notExercised` with that as the reason until you do.
|
|
39
|
+
|
|
40
|
+
## From TypeScript
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { tally, verify } from "@worker-protocol/conformance";
|
|
44
|
+
|
|
45
|
+
const report = await verify({
|
|
46
|
+
baseUrl: "https://fleet.example.com",
|
|
47
|
+
credential: process.env.WORKER_PROTOCOL_CREDENTIAL,
|
|
48
|
+
mayPerform: true,
|
|
49
|
+
arrangement: {
|
|
50
|
+
safeAction: { name: "answer-check", input: { vehicle: "ABC-123", reachable: true } },
|
|
51
|
+
secondCredential: process.env.SECOND_CREDENTIAL,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const counts = tally(report.results);
|
|
56
|
+
for (const { rule, verdict, detail } of report.results) {
|
|
57
|
+
if (verdict === "fails") console.error(`${rule.id} (${rule.file}): ${detail}`);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`verify` also takes a `fetch` of your own, for a test or for a caller that needs its own agent.
|
|
62
|
+
|
|
63
|
+
## The verdicts, and why there are five
|
|
64
|
+
|
|
65
|
+
A report covers **every** rule the edition defines, not only the ones a run exercised. A rule that
|
|
66
|
+
nothing claimed is not silence — it says under its own name why nothing claimed it.
|
|
67
|
+
|
|
68
|
+
| Verdict | What it means |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `passes` | The check ran and the Worker satisfied it. |
|
|
71
|
+
| `fails` | The check ran and the Worker did not. Exit 1. |
|
|
72
|
+
| `notExercised` | The Worker declares no such Capability, or the check needs a Worker *arranged* to be observed and this one is not. A gap somebody can close. |
|
|
73
|
+
| `unverified` | The rule's subject is the Worker, and no party outside it can observe a violation. |
|
|
74
|
+
| `otherSubject` | The rule binds a verifier, a Control Tower, a consumer or an issuer — not a Worker. This tool never contacted whoever it obliges. |
|
|
75
|
+
|
|
76
|
+
`notExercised` never fails the run, and it is deliberately not the same word as `unverified`: they
|
|
77
|
+
read alike on a page and are opposite facts. A report that counted either as compliance would be
|
|
78
|
+
vouching for something nobody checked.
|
|
79
|
+
|
|
80
|
+
Each result carries the rule's id, the specification file that defines it, whether the rule is
|
|
81
|
+
`required` or `recommended`, and one line saying why for every verdict but `passes`. The ids are
|
|
82
|
+
fixed from edition 0.1 on: a rewrite that could change a verdict takes a new id and withdraws the
|
|
83
|
+
old, so a report stays true however long after it was produced somebody reads it.
|
|
84
|
+
|
|
85
|
+
## Arranging a Worker so more can be seen
|
|
86
|
+
|
|
87
|
+
Some rules have no ordinary witness: nothing a tool can do to an unarranged Worker will ever see a
|
|
88
|
+
violation. An Action that succeeds, an input refused on the Worker's own rules, a second credential
|
|
89
|
+
issued to the same holder, a Worker that started moments ago. The arrangement cannot come from the
|
|
90
|
+
protocol — putting test scaffolding into a Descriptor would make every Worker in the network carry
|
|
91
|
+
it — so it arrives the way the base URL and the credential do: out of band, from whoever set it up.
|
|
92
|
+
|
|
93
|
+
`arrangement` takes `safeAction`, `refusedInput`, `asyncAction`, `secondCredential`,
|
|
94
|
+
`consumerCredential`, `unprivilegedCredential`, `justStarted`, `replaceableSettings` and
|
|
95
|
+
`publishedEvent`. Anything not arranged reports `notExercised` naming what was missing.
|
|
96
|
+
|
|
97
|
+
## Editions
|
|
98
|
+
|
|
99
|
+
The verifier declares which edition it holds, and the report carries both that and what the Worker
|
|
100
|
+
declared. A verifier that does not hold the Worker's MAJOR verifies **nothing** and reports that it
|
|
101
|
+
is the one that is behind — rather than failing a Worker for a surface added after this tool was
|
|
102
|
+
built.
|
|
103
|
+
|
|
104
|
+
The rule universe travels inside this package as `rules.json`, generated from the specification, and
|
|
105
|
+
`universe()` hands it back: the rules, the error codes, and the map from a place inside a document
|
|
106
|
+
to the rule that governs it — which is how a report names the obligation that was broken rather
|
|
107
|
+
than announcing that a document is invalid.
|
|
108
|
+
|
|
109
|
+
## What standing it has
|
|
110
|
+
|
|
111
|
+
**Nothing here carries behavior of its own.** Every check reports against a rule id, and a check
|
|
112
|
+
that observed something the specification does not require would be this package making the
|
|
113
|
+
standard. When this tool and the specification disagree, the specification is right and this is the
|
|
114
|
+
bug.
|
|
115
|
+
|
|
116
|
+
## Fixing what it reports, with a coding agent
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
npx skills add rowing-tech/worker-protocol --skill worker-protocol
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
An [Agent Skill](https://agentskills.io) carrying the protocol in any language: what each rule id
|
|
123
|
+
means, where its file is, the surface an implementer without an SDK writes by hand, and the gotchas
|
|
124
|
+
behind the failures this tool reports most. `--all` adds a second one for TypeScript on Hono.
|
|
125
|
+
|
|
126
|
+
## Related packages
|
|
127
|
+
|
|
128
|
+
- `@worker-protocol/schemas` — the Zod objects that generate the normative JSON Schemas.
|
|
129
|
+
- `@worker-protocol/hono` — `mount()`: implement an interface and get every address, header and
|
|
130
|
+
refusal this protocol fixes.
|
|
131
|
+
- `@worker-protocol/client` — `consume()`: read a Worker, and take work from it.
|
|
132
|
+
|
|
133
|
+
## License and name
|
|
134
|
+
|
|
135
|
+
Apache-2.0, patent grant included — implement the protocol in any product, commercial or not,
|
|
136
|
+
without asking anyone. The name is not part of that grant (Apache-2.0 §6).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@worker-protocol/conformance",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"workerProtocolEdition": "0.1",
|
|
5
5
|
"description": "Point it at a Worker's base URL, get a report of what it complies with",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "git+https://github.com/rowing-tech/worker-protocol.git",
|
|
10
10
|
"directory": "packages/conformance"
|
|
11
11
|
},
|
|
12
|
-
"homepage": "https://github.com/rowing-tech/worker-protocol#readme",
|
|
12
|
+
"homepage": "https://github.com/rowing-tech/worker-protocol/tree/main/packages/conformance#readme",
|
|
13
13
|
"bugs": "https://github.com/rowing-tech/worker-protocol/issues",
|
|
14
14
|
"publishConfig": {
|
|
15
15
|
"access": "public"
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"NOTICE"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@worker-protocol/schemas": "0.1.
|
|
36
|
+
"@worker-protocol/schemas": "0.1.2",
|
|
37
37
|
"zod": "^4.5.4"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "26.5.1",
|
|
41
|
-
"@worker-protocol/client": "0.1.
|
|
41
|
+
"@worker-protocol/client": "0.1.2",
|
|
42
42
|
"typescript": "7.0.2",
|
|
43
43
|
"vitest": "5.0.0",
|
|
44
44
|
"wrangler": "4.131.1"
|