@emulates/docker 0.0.0-stage → 1.0.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.
- package/API_EVIDENCE.md +392 -0
- package/CHANGELOG.md +19 -0
- package/DISCOVERY.md +54 -0
- package/ORACLE.md +85 -0
- package/README.md +446 -2
- package/SUPPORT.md +23 -0
- package/dist/chunk-PYYL7YKU.js +629 -0
- package/dist/chunk-PYYL7YKU.js.map +7 -0
- package/dist/chunk-U6P6W4BK.js +4109 -0
- package/dist/chunk-U6P6W4BK.js.map +7 -0
- package/dist/cli.js +805 -0
- package/dist/cli.js.map +7 -0
- package/dist/index.d.ts +1306 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +7 -0
- package/dist/server.d.ts +1804 -0
- package/dist/server.js +12 -0
- package/dist/server.js.map +7 -0
- package/evidence/engine-29.8.0-api-1.52.json +302 -0
- package/openapi.yaml +1188 -0
- package/package.json +121 -4
- package/scripts/docker-oracle.mjs +276 -0
- package/scripts/oracle-client.mjs +229 -0
package/API_EVIDENCE.md
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Docker Engine API evidence
|
|
2
|
+
|
|
3
|
+
US-002 research, retrieved **2026-09-25 UTC**. Status: documentation and pinned
|
|
4
|
+
source inspected; **historical research status, superseded by the US-013 live
|
|
5
|
+
run recorded below**.
|
|
6
|
+
This file defines a planned subset, not an implemented support claim. See
|
|
7
|
+
[boundaries and scenario IDs](../../../docs/INFRASTRUCTURE_MOCKS.md).
|
|
8
|
+
|
|
9
|
+
## Compatibility target and provenance
|
|
10
|
+
|
|
11
|
+
- API target: **v1.52**. The downloaded reference declares Swagger 2.0,
|
|
12
|
+
`info.version: 1.52`, `basePath: /v1.52`.
|
|
13
|
+
- Historical proposed oracle (superseded by user direction in US-013):
|
|
14
|
+
**Docker Engine 29.1.0**, Linux, default API settings.
|
|
15
|
+
This is a reproducible compatibility pin, not a recommendation to downgrade a
|
|
16
|
+
host or a claim of availability. No default Docker socket was queried.
|
|
17
|
+
- Verified upstream tag: `docker-v29.1.0`, commit
|
|
18
|
+
`710302ecf2e958db92cb7d92f8838ea063a31765`. The initial guessed `v29.1.0`
|
|
19
|
+
tag returned 404; it is not the source pin.
|
|
20
|
+
- Pinning evidence: [release tag object](https://api.github.com/repos/moby/moby/git/tags/ab0910fb285e342a43491868a095052ac24308d8),
|
|
21
|
+
[pinned tree](https://github.com/moby/moby/tree/710302ecf2e958db92cb7d92f8838ea063a31765).
|
|
22
|
+
- Versioned docs [D1](https://docs.docker.com/reference/api/engine/version/v1.52.yaml)
|
|
23
|
+
SHA-256: `893db6d64dad76a0662e33557f1689f7b394cbf1a2fa2d1a9dc5e2e2edbe0e25`.
|
|
24
|
+
- Pinned specification [S1](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/api/swagger.yaml)
|
|
25
|
+
SHA-256: `69fe12ce2c6ef1e42a317e5c3d60c9e0dbc5bf4f30e56472ab947975d9a6eedb`.
|
|
26
|
+
Both YAML files were fetched and parsed. Their selected path objects agree
|
|
27
|
+
except that D1 adds a `400` response to ContainerStart; S1 omits it.
|
|
28
|
+
|
|
29
|
+
Immutable source references used below:
|
|
30
|
+
|
|
31
|
+
| ID | Source | Evidence used |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| S2 | [Version middleware](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/middleware/version.go) | Default version for unversioned calls; version errors and response headers |
|
|
34
|
+
| S3 | [Server routing](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/server.go) | Versioned/unversioned route registration; error formatting; unknown path/method |
|
|
35
|
+
| S4 | [Container routes](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/router/container/container_routes.go) | Attach handshake/errors; wait response timing; stop completion |
|
|
36
|
+
| S5 | [Daemon configuration](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/config/config.go) | Maximum 1.52, default minimum 1.44; configurable floor down to 1.24 |
|
|
37
|
+
| S6 | [Container stop](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/stop.go) | Stop waits for termination; cancelling the request does not undo the stop |
|
|
38
|
+
| S7 | [Container state](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/container/state.go) | Wait conditions, immediate results and cancellation |
|
|
39
|
+
| S8 | [Container attach](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/attach.go) | Multiplexed output, raw input, OpenStdin/StdinOnce, paused/restarting conflicts |
|
|
40
|
+
|
|
41
|
+
## Context7 research record
|
|
42
|
+
|
|
43
|
+
Resolved `Docker` with the query “Docker Engine API v1.52 container lifecycle and
|
|
44
|
+
HTTP attach upgrade protocol official documentation.” Selected `/docker/docs`
|
|
45
|
+
because it is the official docs repository. Resolver advertised only
|
|
46
|
+
`__branch__main`, not a pinned v1.52 library version. Three queries were made;
|
|
47
|
+
their results are discovery evidence, not v1.52 verification:
|
|
48
|
+
|
|
49
|
+
| Query scope | Returned source/version | Claim and reconciliation |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| v1.52 attach upgrade, 101, framing, stdin and TTY | [v1.19](https://github.com/docker/docs/blob/main/_vendor/github.com/moby/moby/api/docs/v1.19.md), [v1.23](https://github.com/docker/docs/blob/main/_vendor/github.com/moby/moby/api/docs/v1.23.md), v1.11/v1.17/v1.18 excerpts | Historical raw-stream/upgrade examples. Superseded for this subset by D1/S1 and S4/S8: non-TTY v1.52 upgrade uses multiplexed-stream. |
|
|
52
|
+
| v1.52 create/start/stop/kill/wait/remove lifecycle statuses and conditions | [current SDK examples](https://github.com/docker/docs/blob/main/content/reference/api/engine/sdk/_index.md), [v1.16 stop](https://github.com/docker/docs/blob/main/_vendor/github.com/moby/moby/api/docs/v1.16.md), v1.0/v1.20 excerpts | General create/start/wait and old stop statuses; insufficient for current lifecycle semantics. D1/S1 and S4/S6/S7 supply the pin. |
|
|
53
|
+
| v1.52 discovery, unversioned calls, version rejection, inspect/list | [CLI deprecations](https://github.com/docker/docs/blob/main/_vendor/github.com/docker/cli/docs/deprecated.md), v1.22/v1.44 excerpts; unrelated Docker Agent `/api/ping` | Historical guidance deprecates unversioned calls, but S2/S3 still register/default them in this pin. Docker Agent ping is unrelated and excluded. |
|
|
54
|
+
|
|
55
|
+
The [current API matrix](https://docs.docker.com/reference/api/engine/#api-version-matrix)
|
|
56
|
+
maps Engine 29.0/29.1 to API 1.52. S5, rather than current-main prose, establishes
|
|
57
|
+
the exact selected daemon's defaults. Refresh Context7 and primary evidence before
|
|
58
|
+
adding operation families or changing versions, and before US-010 transport work.
|
|
59
|
+
|
|
60
|
+
## Version routing and rejection policy
|
|
61
|
+
|
|
62
|
+
US-004 refresh (2026-09-27): Context7 `/docker/docs` still exposes only main.
|
|
63
|
+
List/inspect queries returned v1.4/v1.6/v1.56 excerpts; info/rootless queries
|
|
64
|
+
returned v1.12/v1.20/current docs. None replaces the pinned 1.52 source.
|
|
65
|
+
Newly inspected pinned sources are
|
|
66
|
+
[daemon/list.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/list.go),
|
|
67
|
+
[daemon/inspect.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/inspect.go),
|
|
68
|
+
[filters/parse.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/internal/filters/parse.go), and
|
|
69
|
+
[httputils/form.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/httputils/form.go).
|
|
70
|
+
List uses creation-descending order, AND label matching, OR status/exit values,
|
|
71
|
+
unique ID-prefix selection, and name regex matching. A status filter or positive
|
|
72
|
+
limit includes non-running containers. Exited filtering requires a stopped
|
|
73
|
+
container that has started. JSON filter maps accept legacy arrays and boolean
|
|
74
|
+
sets (keys matter even if false); null denotes an empty map. Boolean query
|
|
75
|
+
parsing is permissive: trimmed empty/0/no/false/none are false, other values true.
|
|
76
|
+
The emulator bounds name regex support as documented in README and returns explicit
|
|
77
|
+
501 for other patterns/filters. No installed Engine or differential run was used.
|
|
78
|
+
Pinned [container lookup](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/container.go)
|
|
79
|
+
and [prefix lookup](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/container/view.go)
|
|
80
|
+
confirm full ID, exact name, then unique prefix precedence; ambiguous prefixes
|
|
81
|
+
return InvalidParameter (400), while missing containers return 404.
|
|
82
|
+
List status descriptions follow pinned S7 and its
|
|
83
|
+
[duration formatter](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/vendor/github.com/docker/go-units/duration.go),
|
|
84
|
+
using the injected emulator clock rather than host process uptime.
|
|
85
|
+
|
|
86
|
+
S2/S3 explain why the observed `/v1.52/containers/{id}/attach` and unversioned
|
|
87
|
+
`/info` can belong to one client: every provider route is registered with and
|
|
88
|
+
without a version, and an absent version uses the daemon default (1.52 here).
|
|
89
|
+
Deprecation guidance is not evidence that this pinned daemon rejects `/info`.
|
|
90
|
+
|
|
91
|
+
Planned emulator policy: support v1.52 and unversioned aliases for the listed subset.
|
|
92
|
+
Do not claim to emulate all older APIs merely because the real Engine accepts them.
|
|
93
|
+
For numeric versions above 1.52, use the provider's too-new `400` error; versions
|
|
94
|
+
below the default minimum 1.44 use its too-old `400` error. Versions 1.44–1.51
|
|
95
|
+
are **unsupported by this emulator subset**: return an explicitly Emulates-labelled
|
|
96
|
+
`501` message, not a fictional Engine rejection. Historical compatibility can only
|
|
97
|
+
be expanded with new evidence. Document these emulator-only 501 responses in codegen.
|
|
98
|
+
|
|
99
|
+
Provider version-error message templates from S2 are:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
client version <v> is too new. Maximum supported API version is 1.52
|
|
103
|
+
client version <v> is too old. Minimum supported API version is 1.44, please upgrade your client to a newer version
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
S3 serializes errors as `{"message":"..."}` except requests below API 1.24,
|
|
107
|
+
which receive plain text. Unknown paths/methods use `404` with
|
|
108
|
+
`{"message":"page not found"}`. Malformed version paths are not a promise of
|
|
109
|
+
version negotiation. No automatic client reconnection or fallback is part of
|
|
110
|
+
the emulator. Its declared API support must remain distinct from simulated Engine
|
|
111
|
+
`MinAPIVersion` metadata.
|
|
112
|
+
|
|
113
|
+
## Planned operation contract
|
|
114
|
+
|
|
115
|
+
Paths below are relative to `/v1.52`, also available unversioned as above.
|
|
116
|
+
The status column is the pinned S1 vendor contract; additional implementation
|
|
117
|
+
errors supported by pinned source must be annotated explicitly, not silently
|
|
118
|
+
invented. Global version errors and emulator-only unsupported-feature errors are
|
|
119
|
+
separate from this table. Unless stated otherwise, vendor errors use
|
|
120
|
+
`ErrorResponse` with required string `message`.
|
|
121
|
+
|
|
122
|
+
| Method/path (operation ID) | Inputs and bounded planned behavior | Vendor statuses |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| GET/HEAD `/_ping` (SystemPing/SystemPingHead) | GET body `OK`, HEAD empty; API-Version, Builder-Version, Docker-Experimental, Swarm and cache headers | 200, 500 |
|
|
125
|
+
| GET `/version` (SystemVersion) | Version, ApiVersion, MinAPIVersion, Os, Arch, GitCommit and system/build metadata; simulation labelled in package docs | 200, 500 |
|
|
126
|
+
| GET `/info` (SystemInfo) | Synthetic daemon identity, container counts, operating-system and security observations; availability independent of container state | 200, 500 |
|
|
127
|
+
| GET `/containers/json` (ContainerList) | `all` defaults false, `limit`, `size`; JSON `filters` map. Initial filters: id, name, status, label, exited. Other filters explicitly unsupported | 200, 400, 500 |
|
|
128
|
+
| GET `/containers/{id}/json` (ContainerInspect) | Container ID/name; `size` defaults false. Coherent Id, Name, Image, Config, HostConfig, State and NetworkSettings | 200, 404, 500 |
|
|
129
|
+
| POST `/containers/create` (ContainerCreate) | `name`, `platform`, ContainerConfig plus HostConfig/NetworkingConfig; seeded local image lookup, name uniqueness, immutable Id and Warnings | 201, 400, 404 (image missing), 409 (conflict), 500 |
|
|
130
|
+
| POST `/containers/{id}/start` (ContainerStart) | ID/name; no execution. Supported transition and already-running result; detachKeys/checkpoint features outside initial subset | 204, 304, 404, 500; D1 additionally documents 400 |
|
|
131
|
+
| POST `/containers/{id}/stop` (ContainerStop) | ID/name, signal, integer timeout `t`; pending graceful termination then completion | 204, 304, 404, 500 |
|
|
132
|
+
| POST `/containers/{id}/kill` (ContainerKill) | ID/name, signal (default SIGKILL); supported signal observations, no host signal | 204, 404, 409 (not running), 500 |
|
|
133
|
+
| POST `/containers/{id}/wait` (ContainerWait) | ID/name, condition omitted/empty => not-running; also next-exit and removed | 200, 400, 404, 500 |
|
|
134
|
+
| DELETE `/containers/{id}` (ContainerDelete) | ID/name, force; `v`/`link` default false. Volumes/legacy links outside subset | 204, 400, 404, 409, 500 |
|
|
135
|
+
| POST `/containers/{id}/attach` (ContainerAttach) | Node upgrade only; stream=true, logs=false, stdin/stdout/stderr selections, Tty=false | 101 (upgrade), 200 (real non-upgrade, unsupported here), 400, 404, 500; S8 additionally shows 409 |
|
|
136
|
+
|
|
137
|
+
S1 schemas distinguish container list summaries from inspection. `ContainerState`
|
|
138
|
+
includes Status, Running, Paused, Restarting, OOMKilled, Dead, Pid, ExitCode,
|
|
139
|
+
Error, StartedAt and FinishedAt. A simulated Pid or rootless/security field is not
|
|
140
|
+
host evidence. An image reference in Config.Image, immutable image identity in
|
|
141
|
+
Image, and container Id must not be conflated. Create returns `Id` and `Warnings`;
|
|
142
|
+
wait returns integer `StatusCode` with optional `Error.Message`.
|
|
143
|
+
|
|
144
|
+
Initial creation scope stores Image, Cmd, Entrypoint, Env, Labels, WorkingDir,
|
|
145
|
+
User, attachment/OpenStdin/StdinOnce/Tty flags, StopSignal/StopTimeout and declared
|
|
146
|
+
HostConfig/NetworkingConfig metadata. Mount/resource/network settings are stored
|
|
147
|
+
observations only. Do not accept unsupported configuration as executed or enforced.
|
|
148
|
+
Resolve any newly supported field's validation against S1 before implementation.
|
|
149
|
+
|
|
150
|
+
## Lifecycle details that constrain implementation
|
|
151
|
+
|
|
152
|
+
US-005 refresh (2026-09-27): Context7 returned v1.56/current networking and
|
|
153
|
+
entrypoint examples, used only for discovery. Pinned
|
|
154
|
+
[creation](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/create.go)
|
|
155
|
+
and [configuration merge](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/commit.go)
|
|
156
|
+
establish image resolution, platform warnings, request-over-image environment
|
|
157
|
+
and label precedence, command/entrypoint defaults, empty-entrypoint clearing,
|
|
158
|
+
and `no command specified` (400). The selected 1.52 request fields come from S1.
|
|
159
|
+
The emulator stores launch/host/network configuration without executing it. Full
|
|
160
|
+
daemon resource/network validation and image execution are excluded; the README
|
|
161
|
+
lists the explicit supported subset and emulator-only501 behavior. No real Engine
|
|
162
|
+
creation or host resource operation was performed.
|
|
163
|
+
|
|
164
|
+
- S4/S6: a successful stop `204` follows backend completion. For delayed-stop
|
|
165
|
+
scenarios, keep the HTTP operation pending until modeled termination; an admin
|
|
166
|
+
observation that a stop was received is not an early successful vendor response.
|
|
167
|
+
A lost reply or cancellation does not reverse an already accepted stop. This
|
|
168
|
+
preserves US-007's distinction between request acceptance and actual retirement
|
|
169
|
+
without inventing a 202-like Docker acknowledgement.
|
|
170
|
+
- S7: not-running completes immediately when the condition already holds;
|
|
171
|
+
next-exit does not. Removed waits for removal, which also wakes stop waiters.
|
|
172
|
+
S4 sends HTTP 200 headers before the wait result for this API version, then
|
|
173
|
+
writes the eventual JSON result. Tests must distinguish header arrival from
|
|
174
|
+
body completion and cover client cancellation, reset and shutdown.
|
|
175
|
+
- S1: start on an already-running container and stop on an already-stopped
|
|
176
|
+
container use 304, not a fabricated second transition. Kill on a non-running
|
|
177
|
+
container is a conflict. Force removal kills before removal; it is not a
|
|
178
|
+
permission to remove host resources.
|
|
179
|
+
- Before/after-mutation fault points must preserve state/journal/Timeline evidence
|
|
180
|
+
independently of delivery. No source here proves shared-runtime correctness,
|
|
181
|
+
restart/live-restore, or active socket restoration; those are later test gates.
|
|
182
|
+
|
|
183
|
+
## Attach wire contract and limits
|
|
184
|
+
|
|
185
|
+
For the supported non-TTY upgrade, send `Connection: Upgrade` and `Upgrade: tcp`.
|
|
186
|
+
S4 returns the following header block for v1.52, followed immediately by stream
|
|
187
|
+
bytes (the reader must retain bytes received with the final header fragment):
|
|
188
|
+
|
|
189
|
+
```http
|
|
190
|
+
HTTP/1.1 101 UPGRADED
|
|
191
|
+
Content-Type: application/vnd.docker.multiplexed-stream
|
|
192
|
+
Connection: Upgrade
|
|
193
|
+
Upgrade: tcp
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
D1/S1's old illustrative handshake uses raw-stream, but its framing prose and
|
|
198
|
+
S4 agree on multiplexed-stream for upgraded non-TTY API >=1.42. S4's non-upgrade
|
|
199
|
+
path really uses HTTP 200/raw-stream; it is deliberately excluded from initial
|
|
200
|
+
emulator serving. Fetch cannot represent the raw hijacked duplex connection.
|
|
201
|
+
|
|
202
|
+
Output frames have an 8-byte header: stream byte (1 stdout, 2 stderr), three zero
|
|
203
|
+
bytes, and a uint32 big-endian payload length, followed by exactly that many bytes.
|
|
204
|
+
The spec also describes stream 0 as stdin written to stdout; it is not an input
|
|
205
|
+
framing requirement. S8 wraps output writers only: client stdin is raw bytes,
|
|
206
|
+
enabled only when requested and OpenStdin is true. StdinOnce influences EOF/
|
|
207
|
+
lifetime and needs explicit tests; stdin data must not enter the metadata journal.
|
|
208
|
+
Fragmentation, zero-length payloads, backpressure, EOF and cancellation must be
|
|
209
|
+
tested using an independent consumer. Stream closure alone does not establish
|
|
210
|
+
container termination.
|
|
211
|
+
|
|
212
|
+
Error caveat: S4 handles attach backend errors by hijacking, writing an HTTP error
|
|
213
|
+
with stream content type and a plain-text body, then closing. This differs from
|
|
214
|
+
the specification's generic ErrorResponse schemas. S8 rejects paused/restarting
|
|
215
|
+
containers with conflicts. Implement and test the actual pre-upgrade missing/
|
|
216
|
+
conflict wire errors separately from ordinary JSON REST errors; live oracle
|
|
217
|
+
execution remains necessary to establish observed fidelity.
|
|
218
|
+
|
|
219
|
+
Excluded modes: TTY/PTY, websocket attach, non-upgrade attach, log replay
|
|
220
|
+
(`logs=true`), exec, standalone logs/events, detach-key processing, image
|
|
221
|
+
pull/build, real networking/volumes/__admin/health checks and arbitrary command execution.
|
|
222
|
+
Unsupported modes receive explicit emulator-only 501 errors before upgrade rather
|
|
223
|
+
than silently different successful behavior. Reset/checkout/shutdown terminate
|
|
224
|
+
owned streams and waiters; handles are never serialized into Timeline state.
|
|
225
|
+
|
|
226
|
+
## Verification gaps and oracle requirements
|
|
227
|
+
|
|
228
|
+
The original US-013 proposal required Engine 29.1.0. The user superseded that
|
|
229
|
+
restriction: use the current selected Engine without downgrading the host.
|
|
230
|
+
US-013 now records an authorized Engine 29.8.0 run below, including actual
|
|
231
|
+
version/API configuration, image identity and cleanup evidence. Engine process restart/live-restore
|
|
232
|
+
needs its own scoped operational authorization and evidence. Harness construction
|
|
233
|
+
alone cannot complete that story.
|
|
234
|
+
|
|
235
|
+
US-004–US-012 must resolve exact filter/name matching, signal validation/error
|
|
236
|
+
wrapping, identifier-prefix ambiguity and every newly implemented field against
|
|
237
|
+
this source pin before advertising support. US-010 must refresh attach research,
|
|
238
|
+
test pre-upgrade errors and supported stdin/EOF semantics. Post-mutation history
|
|
239
|
+
capture and stream invalidation remain implementation hypotheses, not upstream
|
|
240
|
+
guarantees. No SDK is claimed pinned or exercised by this research story.
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
### US-006 start/wait implementation evidence
|
|
244
|
+
|
|
245
|
+
Context7 `/docker/docs` was refreshed for start/wait on 2026-09-27. It returned
|
|
246
|
+
current SDK flow examples and older API excerpts, so the pinned sources remain
|
|
247
|
+
authoritative. [Start validation and transitions](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/start.go)
|
|
248
|
+
checks paused before running, returns304 for running/restarting, and409 for
|
|
249
|
+
removal/dead state. S4 rejects start bodies with ContentLength above7 or unknown
|
|
250
|
+
chunked length. S7 preserves FinishedAt across SetRunning, resets ExitCode, and
|
|
251
|
+
notifies all stop waiters at SetStopped; removal also wakes removal-only waiters.
|
|
252
|
+
|
|
253
|
+
The implementation uses explicit admin completion instead of executing a task.
|
|
254
|
+
AutoRemove completes synthetic removal atomically within that synchronous control.
|
|
255
|
+
Wait response headers and completion bodies are separately tested through Fetch
|
|
256
|
+
and Node HTTP; client cancellation, body cancellation, reset, and close release
|
|
257
|
+
transient handles. This is source-backed simulation evidence, not live Engine
|
|
258
|
+
parity. Restart policies, process scheduling and host execution are not simulated.
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
### US-007 termination/removal evidence
|
|
262
|
+
|
|
263
|
+
Context7 `/docker/docs` refreshed stop/kill/remove on 2026-09-27: current SDK/CLI
|
|
264
|
+
stop examples, timeout guidance, and historical v1.6/v1.11 operation excerpts.
|
|
265
|
+
Pinned sources resolve the precise v1.52 semantics:
|
|
266
|
+
|
|
267
|
+
- [kill.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/kill.go): SIGKILL (including an explicit numeric9) waits for exit; other signals acknowledge delivery. Stopped containers conflict. Linux signal names/numbers are validated before lookup.
|
|
268
|
+
- [delete.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/delete.go): concurrent removal conflicts, non-forced running/paused removal conflicts, and force kills before deleting and releasing the name.
|
|
269
|
+
- [signal.go](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/vendor/github.com/moby/sys/signal/signal.go) and [Linux map](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/vendor/github.com/moby/sys/signal/signal_linux.go): zero is invalid; kill restricts to the Linux map (1–31 and34–64). Real-time aliases are supported.
|
|
270
|
+
- S4/S6 and [HTTP status mapping](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/httpstatus/status.go): malformed t returns an unclassified strconv error (500), while a stop signal parsing error is wrapped as System (500). Kill signal errors are InvalidParameter (400). Stop on an already stopped record returns304 before validating its signal.
|
|
271
|
+
|
|
272
|
+
The emulator holds stop/SIGKILL/forced-removal replies until explicit completion;
|
|
273
|
+
acceptance and socket loss never prove retirement. Signal/timeout parameters are
|
|
274
|
+
stored diagnostic metadata; fixture-controlled completion replaces process/timer
|
|
275
|
+
scheduling. v is inert without modeled volumes; link removal is explicit emulator-only501.
|
|
276
|
+
Shared state/checkpoints and transient handles are reused. Fetch and real Node HTTP
|
|
277
|
+
tests cover acceptance versus exit and response loss; no live Engine parity claimed.
|
|
278
|
+
|
|
279
|
+
## US-009 transport implementation evidence
|
|
280
|
+
|
|
281
|
+
Node's [HTTP API](https://nodejs.org/api/http.html) documents the parser header
|
|
282
|
+
limit, receive timeouts and retained connections. The Docker-local transport uses
|
|
283
|
+
these Node facilities plus its own bounded body collector and owned connection
|
|
284
|
+
set. [Node IPC sockets](https://nodejs.org/api/net.html#ipc-support) define local
|
|
285
|
+
path serving and normal server-close cleanup. Transport bounds and path refusal
|
|
286
|
+
are explicit emulator controls, not assertions of Docker daemon limits. Verification
|
|
287
|
+
uses synthetic project-local Unix sockets and TCP, including a built-entry fixture
|
|
288
|
+
executed under Node; it does not use Linux peer credentials or a real Engine.
|
|
289
|
+
|
|
290
|
+
## US-010 handshake implementation refresh
|
|
291
|
+
|
|
292
|
+
Context7 `/docker/docs` was refreshed for v1.52 attach on 2026-09-27 and returned
|
|
293
|
+
v1.23/v1.19/v1.11 examples. Re-reading pinned S4/S8 confirmed the existing wire
|
|
294
|
+
contract above; historical raw-stream examples do not supersede non-TTY v1.52
|
|
295
|
+
multiplexed-stream. The Node path now implements admission/headers and plain-text
|
|
296
|
+
backend errors, with synthetic fragmented-write/initial-byte fixtures and an
|
|
297
|
+
independent raw consumer exercised under Bun and Node. Namespace/branch/fault
|
|
298
|
+
selection stays in shared runtime; private response notes record upgrade101
|
|
299
|
+
without a POST mutation checkpoint. Plain Fetch remains unsupported. Full stream
|
|
300
|
+
framing, stdin semantics and history invalidation are US-011; real parity remains
|
|
301
|
+
US-013. These tests do not establish host enforcement or consumer policy.
|
|
302
|
+
|
|
303
|
+
## US-011 stream framing and lifetime
|
|
304
|
+
|
|
305
|
+
The pinned [stream copier](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/internal/stream/attach.go)
|
|
306
|
+
adds EOF detail to S8: effective stdin copies raw bytes; non-TTY CloseStdin closes
|
|
307
|
+
container input, while the other EOF path closes the attachment's output pipes.
|
|
308
|
+
S8 separately waits for process-not-running for non-TTY StdinOnce. Implemented
|
|
309
|
+
synthetic controls distinguish input EOF, output EOF, cancellation, and explicit
|
|
310
|
+
process completion. Source evidence is not a live-oracle claim. The pinned
|
|
311
|
+
[Linux close notifier](https://github.com/moby/moby/blob/710302ecf2e958db92cb7d92f8838ea063a31765/daemon/server/router/container/notify_linux.go)
|
|
312
|
+
uses EPOLLHUP; portable Node tests assert observed reset/close, not kernel
|
|
313
|
+
provenance. Raw consumers cover fragmented frames, bytes and channel selection,
|
|
314
|
+
input read-ahead/half-close, bounded slow-reader output, peer reset, and instance
|
|
315
|
+
invalidation with stale-handle rejection. Native Node also exercises framing,
|
|
316
|
+
raw input, StdinOnce half-close and process completion.
|
|
317
|
+
|
|
318
|
+
## US-012 — independent consumer verification
|
|
319
|
+
|
|
320
|
+
The package-owned `test/node-consumer.mjs` imports only the built server entry for
|
|
321
|
+
fixture ownership; its clients use native Node HTTP and raw socket bytes over TCP
|
|
322
|
+
and Unix. All mutations, inspections, setup and completion travel through HTTP;
|
|
323
|
+
Node attachment handles supply scripted output/input observation. Both transports
|
|
324
|
+
exercise accepted create/start/stop/kill/remove response loss and re-inspection,
|
|
325
|
+
retained ordinary HTTP connections and fragmented attach with exact binary frames.
|
|
326
|
+
This is independent client/protocol evidence against the emulator, not a real Engine
|
|
327
|
+
oracle or evidence of the external consumer's retry policy.
|
|
328
|
+
|
|
329
|
+
OpenAPI walks assert eligible planned/exercised operation coverage. A seeded
|
|
330
|
+
nonempty list passes unchanged and fails on a deliberate schema-valid State
|
|
331
|
+
mismatch; the existing ping mismatch check remains. Blocking operations and attach
|
|
332
|
+
retain their deterministic lifecycle/protocol evidence. PRD inspection provenance
|
|
333
|
+
identifies raw-socket Docker consumers; there is no declared SDK consumer, no SDK
|
|
334
|
+
pin exercised here, and no SDK compatibility claim.
|
|
335
|
+
|
|
336
|
+
## US-013 — current Engine oracle
|
|
337
|
+
|
|
338
|
+
User direction on 2026-09-27 superseded the exact old-Engine prerequisite: use the
|
|
339
|
+
current Engine and do not downgrade the local Docker installation. Desktop 4.92.0
|
|
340
|
+
reports Engine **29.8.0**, Linux/arm64, GitCommit `3ce5872`, API maximum **1.56**,
|
|
341
|
+
minimum **1.40**. The [official release notes](https://docs.docker.com/engine/release-notes/29/)
|
|
342
|
+
list standalone **29.8.1** as the latest patch; this run establishes 29.8.0 evidence
|
|
343
|
+
only. API **1.52** remains the observed consumer contract and comparison subset.
|
|
344
|
+
This separates the API contract from the executable Engine used as an oracle.
|
|
345
|
+
|
|
346
|
+
Refreshed Context7 `/docker/docs` on 2026-09-27. It returned current negotiation
|
|
347
|
+
and release guidance plus historical v1.17 attach excerpts; those excerpts do not
|
|
348
|
+
establish current wire behavior. Resolved `docker-v29.8.0` through its
|
|
349
|
+
[tag object](https://api.github.com/repos/moby/moby/git/tags/dc4db3d292c317ca216dae9301dffc935c8d7680)
|
|
350
|
+
to commit **3ce5872b7950c63ba2ffbc5123101019ff3e6682**, matching the running daemon.
|
|
351
|
+
Compared selected pinned sources against the prior 29.1.0 source:
|
|
352
|
+
|
|
353
|
+
- [Version middleware](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/server/middleware/version.go),
|
|
354
|
+
[daemon attach](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/attach.go), and
|
|
355
|
+
[stream attach](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/internal/stream/attach.go)
|
|
356
|
+
are unchanged between those pins.
|
|
357
|
+
- [Container routes](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/server/router/container/container_routes.go)
|
|
358
|
+
retain the selected attach/wait paths. Changes include invalid-parameter error
|
|
359
|
+
wrapping, legacy capability rejection and API 1.56 Umask handling; the live
|
|
360
|
+
scenarios do not send those fields or malformed parameters.
|
|
361
|
+
- [Stop](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/stop.go)
|
|
362
|
+
and [kill](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/kill.go)
|
|
363
|
+
now use configured daemon default stop timeout and propagate non-cancelable
|
|
364
|
+
contexts. This oracle uses explicit `stop?t=0` and `kill?signal=KILL`; it does not
|
|
365
|
+
establish custom daemon-default timeout equivalence.
|
|
366
|
+
- [Image/config merge](https://github.com/moby/moby/blob/3ce5872b7950c63ba2ffbc5123101019ff3e6682/daemon/commit.go)
|
|
367
|
+
changes map copying without changing the explicit-entrypoint command merge rule.
|
|
368
|
+
|
|
369
|
+
The authorized live run used an explicit Docker Desktop Unix endpoint and existing
|
|
370
|
+
Linux/arm64 image `sha256:dbbd346860d29f1543e991f30f3284bf4ab5f096d049ecc3426528f20b1b6e6b`.
|
|
371
|
+
No image installation, daemon restart or privileged Engine setup was performed.
|
|
372
|
+
Run `mb-oracle-ab4aefb9657d4b6993bc5f5273593796` passed **29 normalized comparisons**:
|
|
373
|
+
create/start/remove statuses; created/running/exited inspection; 101 attach headers;
|
|
374
|
+
raw stdin echo and separated stdout/stderr bytes; exit 7; stop/kill exit 137;
|
|
375
|
+
wait results and post-removal 404. The three named/labeled containers were confirmed
|
|
376
|
+
absent during cleanup. The [captured JSON report](evidence/engine-29.8.0-api-1.52.json)
|
|
377
|
+
retains actual/model values, image identity, exact Engine version and cleanup.
|
|
378
|
+
|
|
379
|
+
An earlier attempt failed at emulator image seeding before creating any container:
|
|
380
|
+
the PostgreSQL image contained unsupported metadata and declared storage. The
|
|
381
|
+
harness now rejects declared volumes/active healthchecks and projects only modeled
|
|
382
|
+
image defaults, recording omitted metadata. The successful fixture omitted
|
|
383
|
+
`ArgsEscaped` and `ExposedPorts` from synthetic image defaults; no ports were
|
|
384
|
+
published and no config-equivalence claim covers those fields.
|
|
385
|
+
|
|
386
|
+
Normalization excludes dynamic IDs/timestamps, daemon identity/platform fields,
|
|
387
|
+
frame/packet boundaries and cross-channel interleaving. The emulator scripts expected
|
|
388
|
+
process completion; it never executes the image. Existing synthetic response-loss
|
|
389
|
+
checks remain separate from real Engine execution. Daemon restart/live-restore,
|
|
390
|
+
host isolation, SDKs, all API 1.56 features and external consumer policies remain
|
|
391
|
+
unverified. The historical emulator discovery profile remains explicit; this narrow
|
|
392
|
+
live run does not certify every operation/response field against every newer Engine.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog — @emulates/docker
|
|
2
|
+
|
|
3
|
+
## 1.0.0 (2026-10-07)
|
|
4
|
+
|
|
5
|
+
### ⚠️ Breaking changes
|
|
6
|
+
|
|
7
|
+
- point the repo at crvouga/emulates ([cdb5e53](https://github.com/crvouga/emulates/commit/cdb5e536ed8c1f52345e3984f089001c25fdb08a))
|
|
8
|
+
|
|
9
|
+
### Fixes and improvements
|
|
10
|
+
|
|
11
|
+
- format the emulates records query ([8698872](https://github.com/crvouga/emulates/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
- `@emulates/sqlite`
|
|
16
|
+
|
|
17
|
+
## 0.1.1 (2026-10-06)
|
|
18
|
+
|
|
19
|
+
Initial release.
|
package/DISCOVERY.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# @emulates/docker discovery
|
|
2
|
+
|
|
3
|
+
This is the installed-package index for coding agents and tooling. All relative links resolve
|
|
4
|
+
inside `node_modules/@emulates/docker/`; no repository checkout is needed to discover the emulator's
|
|
5
|
+
supported surface or documented behavior.
|
|
6
|
+
|
|
7
|
+
## Capability and behavior sources
|
|
8
|
+
|
|
9
|
+
| Question | Authoritative file | What it contains |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Behaviour and integration | [`README.md`](README.md) | Routes, state transitions, auth, webhooks, controls, presets and deliberate omissions. |
|
|
12
|
+
| Exact capabilities | [`SUPPORT.md`](SUPPORT.md) | Supported, unsupported and parity-covered operations or commands, including reasons for gaps. |
|
|
13
|
+
| Wire contract | [`openapi.yaml`](openapi.yaml) | Machine-readable paths, methods, schemas, responses and parity annotations. |
|
|
14
|
+
| Public API | [`dist/index.d.ts`](dist/index.d.ts) | The installed package's exact TypeScript exports and signatures. |
|
|
15
|
+
| Package metadata | [`package.json`](package.json) | Runtime/entry-point claims, vendor links, parity scope/tier and `emulates.discovery`. |
|
|
16
|
+
|
|
17
|
+
Read these together: the contract/capability matrix says *what* is available, while the README
|
|
18
|
+
defines stateful behavior, lifecycle rules, test controls, and intentional oracle differences.
|
|
19
|
+
If prose and an executable surface disagree, report a parity mismatch instead of adding a
|
|
20
|
+
consumer-side workaround.
|
|
21
|
+
|
|
22
|
+
## Parity and oracle
|
|
23
|
+
|
|
24
|
+
- Declared parity surface: **Docker Engine container lifecycle, logs and streams**.
|
|
25
|
+
- Oracle: **Live vendor API or sandbox**.
|
|
26
|
+
- Repository command: `bun run parity:service -- docker`.
|
|
27
|
+
- Evidence model: Run from an Emulates checkout; credentials come only from .env.local or GitHub Actions secrets. Missing credentials exit 2.
|
|
28
|
+
|
|
29
|
+
The npm package contains evidence summaries and the exact contract, not credentials or the
|
|
30
|
+
repository-only parity harness. Self-parity/property and acceptance tests run in the Emulates
|
|
31
|
+
repository; live parity is an additional oracle check, not a substitute for the packaged matrix.
|
|
32
|
+
|
|
33
|
+
## Runtime introspection
|
|
34
|
+
|
|
35
|
+
- `GET /__admin/health`
|
|
36
|
+
- `GET /__admin`
|
|
37
|
+
- `GET /__admin/state`
|
|
38
|
+
- `GET /__admin/requests`
|
|
39
|
+
- `GET /__admin/metrics`
|
|
40
|
+
- `GET /__admin/faults/presets`
|
|
41
|
+
- `GET /__admin/ui`
|
|
42
|
+
|
|
43
|
+
For HTTP services, use `x-emulates-namespace` (or the documented credential/path carrier) so
|
|
44
|
+
parallel tests do not share state. Admin state, journal, metrics and fault-preset endpoints are
|
|
45
|
+
designed for assertions and diagnosis by consuming test suites.
|
|
46
|
+
|
|
47
|
+
## Report a mismatch or missing capability
|
|
48
|
+
|
|
49
|
+
Follow the [agent reporting contract](https://github.com/crvouga/emulates/blob/main/docs/REPORTING_ISSUES.md). Include package version,
|
|
50
|
+
operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
|
|
51
|
+
documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
|
|
52
|
+
customer data, prompts, PHI, card data, or unredacted recordings.
|
|
53
|
+
|
|
54
|
+
Service key: `docker`.
|
package/ORACLE.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Docker differential oracle
|
|
2
|
+
|
|
3
|
+
This opt-in harness is incomplete evidence until it has run against an explicitly
|
|
4
|
+
authorized Linux Docker Engine supporting the comparison API 1.52. Ordinary tests verify the
|
|
5
|
+
harness against local fixtures; recorded live results are separate evidence.
|
|
6
|
+
|
|
7
|
+
## Preconditions and scope
|
|
8
|
+
|
|
9
|
+
Supply an explicit Unix socket or loopback HTTP endpoint for a disposable Engine.
|
|
10
|
+
The harness never reads Docker contexts, `DOCKER_HOST`, or a default socket. It
|
|
11
|
+
requires the exact Engine version, an existing immutable Linux image ID, a unique
|
|
12
|
+
run ID, and the `--allow-lifecycle` acknowledgment. The flag records the caller's
|
|
13
|
+
intent; it does not grant agent permission. Obtain operational approval first.
|
|
14
|
+
|
|
15
|
+
The image must contain `/bin/sh`, `read`, `printf`, and `sleep`. Images declaring volumes or active healthchecks are rejected before creation.
|
|
16
|
+
Only modeled image defaults are seeded; omitted metadata fields are recorded.
|
|
17
|
+
No image is pulled,
|
|
18
|
+
built, tagged, or deleted. No volumes, host mounts or published ports are used;
|
|
19
|
+
created containers use `NetworkMode: none`. The harness creates at most three
|
|
20
|
+
containers named `<run-id>-attach`, `<run-id>-stop`, and `<run-id>-kill`, with the
|
|
21
|
+
`emulates.oracle=<run-id>` label. The run ID must be `mb-oracle-` followed by
|
|
22
|
+
32 lowercase hexadecimal characters; generate a fresh one for each run.
|
|
23
|
+
|
|
24
|
+
Before creating anything, the harness checks the actual Engine version/OS, image
|
|
25
|
+
identity and absence of all three names. It refuses any collision. Each created
|
|
26
|
+
container is started, inspected and removed. Attach executes a shell that echoes
|
|
27
|
+
one input line, writes a stderr marker and exits 7. Stop and kill use a sleeping
|
|
28
|
+
shell loop; stop uses timeout zero and kill uses SIGKILL. Those scenarios expect
|
|
29
|
+
exit 137. These operations affect only these three containers, not the daemon.
|
|
30
|
+
|
|
31
|
+
Cleanup re-inspects each known create intent and requires matching name, image,
|
|
32
|
+
label and (when returned) immutable container ID before force-removing it. It
|
|
33
|
+
never adopts a definitively rejected create. Unknown ownership fails cleanup
|
|
34
|
+
without deleting the object. Cleanup failures make the run fail and identify the
|
|
35
|
+
run-owned name needing investigation. Abrupt process/host termination can prevent
|
|
36
|
+
cleanup; preserve the run ID and inspect ownership before any manual cleanup.
|
|
37
|
+
|
|
38
|
+
## Invocation
|
|
39
|
+
|
|
40
|
+
Build the package, then run from its directory after obtaining approval:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
node scripts/docker-oracle.mjs \
|
|
44
|
+
--endpoint unix:///absolute/path/to/approved-engine.sock \
|
|
45
|
+
--engine-version 29.8.0 \
|
|
46
|
+
--image sha256:<64-lowercase-hex-image-id> \
|
|
47
|
+
--run-id mb-oracle-<32-lowercase-hex-run-id> \
|
|
48
|
+
--allow-lifecycle
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
A loopback endpoint such as `http://127.0.0.1:23750` is also supported. Placeholders
|
|
52
|
+
are rejected. Authenticated/TLS endpoints are outside this harness; use an
|
|
53
|
+
explicitly authorized local endpoint or tunnel. The numeric Engine version must match the endpoint exactly. The selected API
|
|
54
|
+
must be within its advertised minimum/maximum range. Record each new tested
|
|
55
|
+
Engine version; do not require downgrading the user's host.
|
|
56
|
+
|
|
57
|
+
## Comparison and evidence
|
|
58
|
+
|
|
59
|
+
The JSON report records actual Engine/API/platform information, immutable image,
|
|
60
|
+
normalized comparisons, cleanup results and gaps. Exit status is nonzero on a
|
|
61
|
+
comparison, setup or cleanup failure. Preserve that report under the project's
|
|
62
|
+
ignored `.emulates/` directory, then summarize verified evidence in
|
|
63
|
+
`API_EVIDENCE.md`; do not turn absent execution into a passing result.
|
|
64
|
+
|
|
65
|
+
Comparisons cover create/start/remove HTTP statuses, inspect execution state,
|
|
66
|
+
wait exit code, attach upgrade headers and stdout/stderr bytes. Multiplexed output
|
|
67
|
+
is decoded independently and concatenated by channel, removing arbitrary frame
|
|
68
|
+
and packet boundaries. Output bytes are recorded as base64. Container IDs,
|
|
69
|
+
timestamps, daemon-specific metadata and cross-channel interleaving are not
|
|
70
|
+
compared. The emulator's completion control scripts the known exit behavior; it does
|
|
71
|
+
not execute the image. Tests of image execution or host isolation are not implied.
|
|
72
|
+
|
|
73
|
+
The harness performs no daemon restart or live-restore operation. Existing
|
|
74
|
+
synthetic transport response-loss tests are separate evidence and do not establish
|
|
75
|
+
real restart/live-restore behavior. This harness does not verify an SDK or
|
|
76
|
+
Initiative's recovery policies.
|
|
77
|
+
|
|
78
|
+
## Recorded run
|
|
79
|
+
|
|
80
|
+
On 2026-09-27, Desktop 4.92.0 / Engine 29.8.0 (Linux/arm64, API range
|
|
81
|
+
1.40–1.56) passed all 29 comparisons at API 1.52. All three containers were
|
|
82
|
+
confirmed absent afterward. See [the captured report](evidence/engine-29.8.0-api-1.52.json)
|
|
83
|
+
and [source reconciliation](API_EVIDENCE.md#us-013--current-engine-oracle).
|
|
84
|
+
This does not claim testing of standalone Engine 29.8.1, all API 1.56 features,
|
|
85
|
+
or matching daemon identity fields from `/version` and `/info`.
|