awp-python 0.1.0a2__tar.gz → 0.1.0a3__tar.gz
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.
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/CHANGELOG.md +10 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/PKG-INFO +8 -7
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/README.md +7 -6
- awp_python-0.1.0a3/conformance/README.md +86 -0
- awp_python-0.1.0a3/conformance/core-agent-lockstep.json +1496 -0
- awp_python-0.1.0a3/conformance/core-agent-streaming.json +1498 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/conformance/core-world-lockstep.json +61 -47
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/conformance/core-world-streaming.json +60 -46
- awp_python-0.1.0a3/conformance/features-lockstep.json +1671 -0
- awp_python-0.1.0a3/conformance/features-streaming.json +1671 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/pyproject.toml +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/__init__.py +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-status.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-submit-result.schema.json +1 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/approval-respond.schema.json +4 -4
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/common.schema.json +3 -3
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/error.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/frame-inline.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/obs-report.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/safety-policy.schema.json +1 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-ready.schema.json +2 -2
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-state.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/world-event.schema.json +1 -1
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/aio.py +45 -10
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/client.py +62 -10
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/frames.py +4 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/config.py +1 -0
- awp_python-0.1.0a3/src/awp_sim/demo.py +133 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/server.py +2 -2
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/session.py +20 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/world.py +63 -22
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_evidence.py +43 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_features.py +75 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_streams.py +17 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_world.py +34 -0
- awp_python-0.1.0a2/conformance/README.md +0 -63
- awp_python-0.1.0a2/src/awp_sim/demo.py +0 -85
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/.gitignore +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/.gitmodules +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/.python-version +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/LICENSE +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/scripts/check_traces.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/scripts/sync_spec.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/lifecycle.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-cancel-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-ref.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-schema.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/action-submit.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/agent-manifest.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/approval-requested.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/embodiment.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/empty-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/frame-tree.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/observation-channel.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/ping-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/ping.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/profiles/gui-actions.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/reset-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/reset.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/restore.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-open.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-resume.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-telemetry.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-transfer-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/session-transfer.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/snapshot-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/subscribe-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/subscribe.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/task-update.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/tick-result.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/tick.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/unsubscribe.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/_spec/schemas/world-manifest.schema.json +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/clock.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/errors.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/jsonrpc.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/lifecycle.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/py.typed +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp/schema.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/__init__.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/__main__.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/arm.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/audit.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/cli.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/loopback.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/py.typed +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/recorder.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/replay.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/src/awp_sim/scenarios.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/__init__.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/conftest.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/helpers.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_audit.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_cli.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_client_traces.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_e2e.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_frames.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_regressions.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_scenarios.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/tests/test_schema.py +0 -0
- {awp_python-0.1.0a2 → awp_python-0.1.0a3}/uv.lock +0 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0a3
|
|
4
|
+
|
|
5
|
+
Targets specification revision `0.1-draft.9`.
|
|
6
|
+
|
|
7
|
+
- `awp_sim`: standing approvals (AWP-APR-004), declared as `safety_policy.standing_approvals` with the approval feature; a submission within a grant is admitted without approval and its result names the grant's `approval_id`.
|
|
8
|
+
- `awp`: `AsyncClient.advance` returns once every subscribed per-tick channel holds a frame of the new tick, which on a stream connection may follow the result (AWP-TIM-003). A `session.resume` answered `AWP_SESSION_UNKNOWN` closes the session and forgets its actions (AWP-SES-008). `respond_approval` takes `standing`.
|
|
9
|
+
- `awp-sim demo` resumes after a lost connection, or opens a new session if the world no longer holds it.
|
|
10
|
+
- `awp_sim`: an integer beyond 2^53-1 closes the session with reason `protocol_error` and the connection with code 1002 (AWP-CTL-009); a malformed frame on a stream connection closes it with code 1002 and `AWP_MALFORMED` (AWP-DAT-010); after a lockstep resumption every per-tick channel restarts with a resync keyframe at the current tick (AWP-TIM-009); after a reset the fresh frames precede the result (AWP-PRM-006).
|
|
11
|
+
- `awp`: an integer beyond 2^53-1 ends the session with `session.close` and close code 1002; a malformed stream frame is dropped and its stream connection closed and re-established; frames with `resync` but not `keyframe` are malformed. While a lost stream connection is down, `AsyncClient.command` raises instead of sending inline (AWP-TRN-010). `ClientConnection.receive_frame` raises for a malformed frame, and `delivery()` reports each channel's frames and gaps.
|
|
12
|
+
|
|
3
13
|
## 0.1.0a2
|
|
4
14
|
|
|
5
15
|
Targets specification revision `0.1-draft.8`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: awp-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a3
|
|
4
4
|
Summary: Agent World Protocol client protocol layer and reference world for Python.
|
|
5
5
|
Project-URL: Specification, https://www.agentworldprotocol.com
|
|
6
6
|
Project-URL: Source, https://github.com/Hyperduality/awp-python
|
|
@@ -26,23 +26,24 @@ Python implementation of the [Agent World Protocol](https://www.agentworldprotoc
|
|
|
26
26
|
- **`awp`** — the client protocol layer. `ClientConnection` is the agent side of AWP as a sans-IO state machine; `awp.aio.AsyncClient` drives it over a WebSocket.
|
|
27
27
|
- **`awp_sim`** — the reference world. A sans-IO world engine with a simulated arm, a WebSocket server, an audit log, and a scenario suite that records wire traces.
|
|
28
28
|
|
|
29
|
-
It targets specification revision **`0.1-draft.
|
|
29
|
+
It targets specification revision **`0.1-draft.9`**, pinned as the `spec/` submodule. This is an alpha: the API will change with the draft.
|
|
30
30
|
|
|
31
31
|
## Status
|
|
32
32
|
|
|
33
|
-

|
|
34
|
+

|
|
34
35
|
|
|
35
|
-
The world is **Core World: AWP-conformant against 0.1-draft.
|
|
36
|
+
The world is **Core World: AWP-conformant against 0.1-draft.9**, and the client, through its demo agent, **Core Agent: AWP-conformant against 0.1-draft.9**, each in both time models: [awp-conformance](https://github.com/Hyperduality/awp-conformance) reports no failure and nothing untested, and [`conformance/`](conformance/README.md) holds the reports and the evidence for their manual rows. The **sim** profile in lockstep is *self-assessed against 0.1-draft.9*: the suite reports no failure and leaves a few requirements untested. Every recorded trace also passes the spec's own checker, which verifies schemas, the action lifecycle table, idempotency, replay, and frame sequencing.
|
|
36
37
|
|
|
37
38
|
| Implemented | Not implemented |
|
|
38
39
|
|---|---|
|
|
39
40
|
| Lockstep (`on_tick`, `any_session`) and streaming | `barrier` tick authority |
|
|
40
41
|
| Inline and `ws` stream bindings; binary frame codec (all spec vectors) | Other stream bindings (`webrtc`, `webtransport`, `shm`, `grpc`) |
|
|
41
|
-
| Full action lifecycle; preemption (`replace`, `queue`, `reject`, `blend`); idempotency |
|
|
42
|
+
| Full action lifecycle; preemption (`replace`, `queue`, `reject`, `blend`); idempotency | Grant expiry |
|
|
42
43
|
| Watchdog and safe state, heartbeats, resumption with replay and acknowledgement | Multi-bind and shared control (one embodiment) |
|
|
43
44
|
| Spatial, velocity, and rate envelopes (`command_check`), monitored during execution | Robotics profile (a simulated arm proves nothing physical) |
|
|
44
45
|
| Audit log with redaction and hash chain; e-stop; `world.reset` | |
|
|
45
|
-
| Beyond Core (`--features`): task, approval, transfer, seeding, snapshots, replay bundles, a servo command channel | |
|
|
46
|
+
| Beyond Core (`--features`): task, approval and standing approvals, transfer, seeding, snapshots, replay bundles, a servo command channel | |
|
|
46
47
|
|
|
47
48
|
## Quickstart
|
|
48
49
|
|
|
@@ -109,7 +110,7 @@ The connection tracks the action lifecycle against the spec's transition table,
|
|
|
109
110
|
src/awp/ client protocol layer (sans-IO), asyncio adapter, frame codec, schemas
|
|
110
111
|
src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
|
|
111
112
|
src/awp_sim/ world engine, arm, server, audit log, loopback, scenarios, CLI
|
|
112
|
-
spec/ agent-world-protocol, pinned at spec-v0.1-draft.
|
|
113
|
+
spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
|
|
113
114
|
scripts/ spec sync and trace checking
|
|
114
115
|
```
|
|
115
116
|
|
|
@@ -5,23 +5,24 @@ Python implementation of the [Agent World Protocol](https://www.agentworldprotoc
|
|
|
5
5
|
- **`awp`** — the client protocol layer. `ClientConnection` is the agent side of AWP as a sans-IO state machine; `awp.aio.AsyncClient` drives it over a WebSocket.
|
|
6
6
|
- **`awp_sim`** — the reference world. A sans-IO world engine with a simulated arm, a WebSocket server, an audit log, and a scenario suite that records wire traces.
|
|
7
7
|
|
|
8
|
-
It targets specification revision **`0.1-draft.
|
|
8
|
+
It targets specification revision **`0.1-draft.9`**, pinned as the `spec/` submodule. This is an alpha: the API will change with the draft.
|
|
9
9
|
|
|
10
10
|
## Status
|
|
11
11
|
|
|
12
|
-

|
|
13
|
+

|
|
13
14
|
|
|
14
|
-
The world is **Core World: AWP-conformant against 0.1-draft.
|
|
15
|
+
The world is **Core World: AWP-conformant against 0.1-draft.9**, and the client, through its demo agent, **Core Agent: AWP-conformant against 0.1-draft.9**, each in both time models: [awp-conformance](https://github.com/Hyperduality/awp-conformance) reports no failure and nothing untested, and [`conformance/`](conformance/README.md) holds the reports and the evidence for their manual rows. The **sim** profile in lockstep is *self-assessed against 0.1-draft.9*: the suite reports no failure and leaves a few requirements untested. Every recorded trace also passes the spec's own checker, which verifies schemas, the action lifecycle table, idempotency, replay, and frame sequencing.
|
|
15
16
|
|
|
16
17
|
| Implemented | Not implemented |
|
|
17
18
|
|---|---|
|
|
18
19
|
| Lockstep (`on_tick`, `any_session`) and streaming | `barrier` tick authority |
|
|
19
20
|
| Inline and `ws` stream bindings; binary frame codec (all spec vectors) | Other stream bindings (`webrtc`, `webtransport`, `shm`, `grpc`) |
|
|
20
|
-
| Full action lifecycle; preemption (`replace`, `queue`, `reject`, `blend`); idempotency |
|
|
21
|
+
| Full action lifecycle; preemption (`replace`, `queue`, `reject`, `blend`); idempotency | Grant expiry |
|
|
21
22
|
| Watchdog and safe state, heartbeats, resumption with replay and acknowledgement | Multi-bind and shared control (one embodiment) |
|
|
22
23
|
| Spatial, velocity, and rate envelopes (`command_check`), monitored during execution | Robotics profile (a simulated arm proves nothing physical) |
|
|
23
24
|
| Audit log with redaction and hash chain; e-stop; `world.reset` | |
|
|
24
|
-
| Beyond Core (`--features`): task, approval, transfer, seeding, snapshots, replay bundles, a servo command channel | |
|
|
25
|
+
| Beyond Core (`--features`): task, approval and standing approvals, transfer, seeding, snapshots, replay bundles, a servo command channel | |
|
|
25
26
|
|
|
26
27
|
## Quickstart
|
|
27
28
|
|
|
@@ -88,7 +89,7 @@ The connection tracks the action lifecycle against the spec's transition table,
|
|
|
88
89
|
src/awp/ client protocol layer (sans-IO), asyncio adapter, frame codec, schemas
|
|
89
90
|
src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
|
|
90
91
|
src/awp_sim/ world engine, arm, server, audit log, loopback, scenarios, CLI
|
|
91
|
-
spec/ agent-world-protocol, pinned at spec-v0.1-draft.
|
|
92
|
+
spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
|
|
92
93
|
scripts/ spec sync and trace checking
|
|
93
94
|
```
|
|
94
95
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Conformance
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
| Class | Configuration | Claim | Report |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| Core World | `awp-sim serve --mode lockstep` | Core World (lockstep): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-world-lockstep.json`](core-world-lockstep.json) |
|
|
8
|
+
| Core World | `awp-sim serve` | Core World (streaming): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-world-streaming.json`](core-world-streaming.json) |
|
|
9
|
+
| Core World + sim | `awp-sim serve --mode lockstep --features task,approval,blend,transfer,sim --approver-token awp-sim-approver` | Core World + sim (lockstep): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`features-lockstep.json`](features-lockstep.json) |
|
|
10
|
+
| Core World | `awp-sim serve --features task,approval,blend,transfer,servo --stream-binding ws --approver-token awp-sim-approver --approval-timeout-ms 5000` | Core World (streaming): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`features-streaming.json`](features-streaming.json) |
|
|
11
|
+
| Core Agent | `awp-sim demo`, lockstep manifest | Core Agent (lockstep): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-agent-lockstep.json`](core-agent-lockstep.json) |
|
|
12
|
+
| Core Agent | `awp-sim demo`, streaming manifest | Core Agent (streaming): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-agent-streaming.json`](core-agent-streaming.json) |
|
|
13
|
+
|
|
14
|
+
Each report, from awp-conformance 0.1.0a3 against awp-python 0.1.0a3, has no failure and nothing untested; the evidence for its `manual` rows follows (AWP-CNF-005). The feature configurations cover every feature awp-sim offers; `sim` and `servo` need separate runs, since `sim` is lockstep-only and `servo` streaming-only. The streaming one shortens `approval_timeout_ms` so the suite can wait out a timeout (AWP-APR-003).
|
|
15
|
+
|
|
16
|
+
## Reproduce
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install --pre awp-python awp-conformance
|
|
20
|
+
curl -LO https://raw.githubusercontent.com/Hyperduality/awp-conformance/v0.1.0a3/fixtures/awp-sim.json
|
|
21
|
+
awp-sim serve --mode lockstep & # or `awp-sim serve` for streaming
|
|
22
|
+
export AWP_SIM_PID=$!
|
|
23
|
+
awp-conformance world ws://127.0.0.1:8710 --fixture awp-sim.json --out report/
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For the feature configurations, serve with the flags in the table and use `fixtures/awp-sim-features.json` (and `--profile sim` in lockstep). The fixture's e-stop hooks signal `$AWP_SIM_PID`; without it the e-stop test is skipped and AWP-EVT-002 is reported untested. The agent claims test the demo agent, which is written on the `awp` client, against the suite's harness world:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
awp-sim manifest --mode lockstep > manifest.json # or --mode streaming
|
|
30
|
+
echo '{"proprio": {"p_m": [0, 0, 0.4], "v_mps": [0, 0, 0]}, "arm_state": {"phase": "idle", "target_m": null, "action_id": null}}' > frames.json
|
|
31
|
+
awp-conformance agent --manifest manifest.json --frames frames.json --out report/ -- awp-sim demo --url '{url}' --token '{token}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The tests cited below run in this repository's CI:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv run pytest tests/test_frames.py tests/test_evidence.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Manual evidence
|
|
41
|
+
|
|
42
|
+
### AWP-DAT-002, AWP-TRN-009 — latest-wins delivery (streaming)
|
|
43
|
+
|
|
44
|
+
- **Drop policy.** Each connection's send queue (`_Outbox`, [`src/awp_sim/server.py`](../src/awp_sim/server.py)) holds at most one unsent frame per latest-wins channel and replaces it when a newer one is produced; control messages and reliable frames queue in order, so a stalled latest-wins channel delays them by at most its one pending frame. A peer that stops reading is disconnected at 10,000 pending items rather than buffered without limit.
|
|
45
|
+
- **Stalled-receiver test.** `test_a_stalled_receiver_holds_one_frame_per_latest_wins_channel`: 1,000 `proprio` frames and 10 `arm_state` frames are produced while nothing drains the queue; one `proprio` frame, the newest, and all 10 `arm_state` frames remain, in order.
|
|
46
|
+
|
|
47
|
+
### AWP-DAT-001, AWP-DAT-009 — loss accounting at the receiver (Core Agent, lockstep)
|
|
48
|
+
|
|
49
|
+
In streaming the suite reads the agent's loss accounting from its `obs.report`; lockstep sessions send none, so the rows are `manual` there.
|
|
50
|
+
|
|
51
|
+
- `test_the_receiver_counts_seq_gaps_as_loss_but_not_the_gap_before_a_resync`: in each time model, frames skipping two `seq` values on one channel count two missing frames in `ClientConnection.delivery()`, and a resync frame after a gap of five on another counts none.
|
|
52
|
+
- The client holds no delta state: each frame reaches the application whole, with its `keyframe` and `resync` flags.
|
|
53
|
+
|
|
54
|
+
### AWP-AUD-005 — replay bundles (Core World + sim)
|
|
55
|
+
|
|
56
|
+
`test_a_replay_bundle_reproduces_its_session` (`tests/test_features.py`) records a seeded lockstep session with a cancel and a second move as a replay bundle, replays it with `awp-sim replay`'s engine, and reproduces every transition and more than 80 frame hashes; a bundle with one tampered frame hash does not reproduce. `awp-sim serve --replay-dir DIR --mode lockstep --features sim` writes bundles, and `awp-sim replay BUNDLE` checks one.
|
|
57
|
+
|
|
58
|
+
### AWP-DAT-008 — frame test vectors
|
|
59
|
+
|
|
60
|
+
World and agent share one decoder, `awp.frames`. `test_vectors` (`tests/test_frames.py`) decodes every vector in `schemas/test-vectors/frames.json` of the `spec/` submodule, pinned at `spec-v0.1-draft.9`: the 10 valid vectors to the listed fields, and the 7 marked `expect_error` rejected with the listed error. `test_roundtrip_without_vendor` re-encodes the 8 valid vectors without an unknown extension or reserved bits byte for byte.
|
|
61
|
+
|
|
62
|
+
### AWP-ENV-003 — envelope violations during execution
|
|
63
|
+
|
|
64
|
+
After every simulation step the world checks the arm against its envelope: position within `aabb_m`, speed within `max_velocity_mps`. On leaving it, the world stops the arm, emits `world.event: envelope_violation` to every session, and fails the executing action with reason `envelope` once its safe abort completes. An external disturbance is injected with `World.disturb(offset_m)` (or `Server.disturb`).
|
|
65
|
+
|
|
66
|
+
- `test_a_disturbance_during_execution_fails_the_action`: in each time model, a move is executing when the arm is pushed out of the envelope; the world emits `envelope_violation` and the move ends `failed` with reason `envelope`.
|
|
67
|
+
- `test_commanded_motion_never_leaves_the_envelope`: 400 seeded random submissions, replacements, queued moves, stops, and cancels in each time model, checked after every advance; no violation is reported.
|
|
68
|
+
- `test_servo_motion_never_leaves_the_envelope`: servo setpoints toward the walls, and stops during them.
|
|
69
|
+
|
|
70
|
+
### AWP-UNI-001 — SI units and unit suffixes
|
|
71
|
+
|
|
72
|
+
The fields awp-sim defines, reviewed:
|
|
73
|
+
|
|
74
|
+
| Field | Where | Unit |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `p_m` | `proprio` payload | m |
|
|
77
|
+
| `v_mps` | `proprio` payload; `servo_arm` setpoints | m/s |
|
|
78
|
+
| `target_m` | `arm_state` payload | m |
|
|
79
|
+
| `max_velocity_mps` | `move_to_pose` params | m/s |
|
|
80
|
+
| `phase`, `action_id` | `arm_state` payload | not physical |
|
|
81
|
+
|
|
82
|
+
Every other field is defined by the specification's schemas. `test_world_defined_fields_carry_si_suffixes` collects every action parameter, channel schema field, and payload field across every feature, and fails on any field not reviewed as non-physical that lacks a unit suffix.
|
|
83
|
+
|
|
84
|
+
### AWP-VER-009 — the draft revision is named
|
|
85
|
+
|
|
86
|
+
The [README](../README.md) and the [awp-sim page](https://www.agentworldprotocol.com/adapters/awp-sim) name `0.1-draft.9`; `awp.SPEC_REVISION` is `"0.1-draft.9"`; the `spec/` submodule is pinned at the tag `spec-v0.1-draft.9`; each report records `"specification": "0.1-draft.9"` and its claim names the revision.
|