VAEP v1.0.0-rc2
Superseded by v1.0.0-rc3, which carries both errata below unchanged.
rc2 as published is unsafe in two places. Apply rc2 errata 1 (2026-10-16) before relying on rc2. The rc2 conformance claim is withheld until an installation has applied both errata.
Artifacts
| Artifact | SHA-256 |
|---|---|
VAEP_Specification_v1.0.0-rc2.pdfSpecification, as published | fe3c3f9edd3987f5ff288d44eb773eed50551f4bbc99dc940859373977bb9128 |
vaep-conformance-1.0.0rc2.zipConformance package, as published | c5c031b7800dc060231814d922b1b42fd4aecc655c530e161ceac56883063204 |
| vaep-conformance-1.0.0rc2-errata1.zip Conformance package with rc2 errata 1 applied | f2a36e24e13ebb6f628982894e0d43c0579d6cc69d8bb1a6bcd04826abdba9de |
Errata
| Version | Date | Page | SHA-256 |
|---|---|---|---|
| rc2 errata 1 | 2026-10-16 | vaep-v1.0.0-rc2-errata-1.md | 8809acce5c120679ac4bf53efbccb102fe13d77ed2569c32d6f1952cefc978c2 |
VAEP v1.0.0-rc2: errata
Version: rc2 errata 1. Date: 2026-10-16. Issued under: GOV-04.
Corrects: VAEP_Specification_v1.0.0-rc2.pdf (SHA-256 fe3c3f9edd3987f5ff288d44eb773eed50551f4bbc99dc940859373977bb9128) and its conformance package vaep-conformance-1.0.0rc2.zip
(SHA-256 c5c031b7800dc060231814d922b1b42fd4aecc655c530e161ceac56883063204).
Patched package: vaep-conformance-1.0.0rc2-errata1.zip (SHA-256 f2a36e24e13ebb6f628982894e0d43c0579d6cc69d8bb1a6bcd04826abdba9de), at https://vaep.x3lab.dev/vaep-conformance-1.0.0rc2-errata1.zip. Its
ERRATA.md lists every file that differs from the rc2 package.
This page's SHA-256 is recorded in the VAEP repository (errata/rc2-errata-1.sha256), with the hashes
above. The text of each erratum is identical to §1 of VAEP v1.0.0-rc3, which carries both unchanged.
Status
These two corrections are issued as rc2 errata because rc2 as published is unsafe in both places.
- Each takes effect on publication.
- Implementations have 30 days to apply them, but the rc2 conformance claim is withheld from publication until an installation has applied both.
- Until then, an installation MUST disable autonomous execution of actions with money effects, or document an equivalent compensating control in its conformance report.
| Erratum | rc2 requirement corrected | rc2 section |
|---|---|---|
| ERRATUM-1 | AUTH-02 | §10.2, Capability Grant |
| ERRATUM-2 | AUTH-11, last sentence | §10.2, Capability Grant (server-side budget ledger) |
ERRATUM-1 — Access-token jti versus DPoP proof jti
Original (AUTH-02): "…every jti and DPoP proof jti MUST be rejected on reuse within the token lifetime."
Defect: Rejecting reuse of the access token's jti makes every grant single-use. That contradicts the 15-minute grant lifetime and RFC 9449, under which one DPoP-bound access token is presented on many requests, each with a fresh proof.
Replacement (AUTH-02, corrected): Grants MUST be sender-constrained with DPoP (RFC 9449) using server-issued nonces. The access token's jti identifies the token for revocation and audit. The gateway MUST NOT reject a request solely because the token's jti was seen before. Each DPoP proof's jti MUST be rejected on reuse within the replay-retention window (AUTH-16). The remaining AUTH-02 text is unchanged.
Fixtures:
- add test
access_token_multi_request_accepted; - add test
dpop_proof_replay_rejected; - add a negative control: with the proof replay cache disabled, the replay test fails;
- retire any rc2 fixture asserting rejection of access-token
jtireuse.
Migration: Drop access-token jti entries from the replay cache and keep proof jti entries. No data migration.
Fixtures that check it:
- rc2 package, errata 1 (
tests/test_vpl_identity_grants.py):test_access_token_multi_request_accepted,test_dpop_proof_replay_rejected,test_dpop_key_mismatch,test_dpop_proof_without_jti_rejected, and the negative controltest_negative_control_proof_replay_cache_disabled. - Retired:
test_dpop_mismatch_and_replay, which asserted rejection of access-tokenjtireuse. It stays in the package markedretiredwith ERRATUM-1 as the reason; it does not run and does not count toward AUTH-02's coverage. Its DPoP-key half continues astest_dpop_key_mismatch. - VAEP rc3 suite (
tests/gateway/test_auth.py):test_access_token_multi_request_accepted,test_dpop_proof_replay_rejected,test_negative_control_proof_replay_cache_disabled.
ERRATUM-2 — Budget reservation released on timeout
Original (AUTH-11): "…committed on success, and released on failure or after 10 minutes."
Defect: A reservation can be released while its effect has been dispatched or may have completed, for example with a slow provider or a crashed worker. The released amount can then be spent again, so cumulative caps such as total refunds can be exceeded.
Replacement (AUTH-11, last sentence), self-contained for rc2: A reservation is never released by elapsed time. It is:
- committed on recorded success of its action;
- released on a recorded rollback, or on a recorded provider response documented as non-executing;
- otherwise held for human reconciliation.
In rc3, EXE-07 supersedes this sentence with the full reservation state machine.
Fixtures:
- add test
reservation_not_released_after_commit_timeout; - add fault-injection boundaries 5, 6 and 9 (CNF-09);
- add a negative control: restoring the 10-minute release makes the cap-overspend test fail.
Migration: Before the erratum counts as applied, audit every reservation that was released by timeout while an outbox row or provider request existed. Re-reserve or reconcile each one.
Fixtures that check it:
- VAEP rc3 suite (
tests/protocol/test_dispatch.py):test_reservation_not_released_after_commit_timeoutand the negative controltest_negative_control_ten_minute_release_overspends_the_cap; CNF-09 fault-injection boundaries 5, 6 and 9. - rc2 package: no fixture conflicts with ERRATUM-2 (its reference ledger never releases a reservation by elapsed time), so errata 1 changes nothing there.