Skip to content

test(did-webvh): regression tests for same-second versionTime collision (#600) - #605

Merged
stormer78 merged 1 commit into
mainfrom
worktree-fix-offline-didcomm-enable-republish
Jul 2, 2026
Merged

test(did-webvh): regression tests for same-second versionTime collision (#600)#605
stormer78 merged 1 commit into
mainfrom
worktree-fix-offline-didcomm-enable-republish

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Root cause

Investigating the reported bug — offline vta services didcomm enable updates config but the VTA's did:webvh document keeps advertising REST only (versionId stays 1-) — traced to the same-second versionTime collision, not an offline-vs-online split.

  • The offline path (services_cli::run_services_didcomm_enableenable_didcommupdate_did_webvh) does reach the WebVH LogEntry publish step; it has since the op was written. It is not "returns after only writing config" — update_did_webvh runs first, then config.toml is written.
  • The genesis entry (from vta setup) and the enable's update entry are minted in the same wall-clock second. did:webvh serialises versionTime at second granularity and requires each entry to be strictly later than the previous, so entry 2 collides. config.toml still gets written because the library stamps the entry without validating strict-increase at build time — the failure only surfaces when a client resolves did.jsonl, which truncates the log back to the version-1 REST-only state.
  • This affects both transports (online pnm services didcomm enable and offline vta …) — any create-then-update in the same second.
  • The double-quoted mediator_url from the report is not reproducible on current code: resolve_mediator extracts the endpoint via ServiceEndpoint::get_uri() (clean string). It points at a double-encoded serviceEndpoint on the mediator side, not a VTA config-writer bug.

Already fixed on main

The bug is already fixed by PR #600 (c73d9db, "backdate + space the VTA's webvh versionTime"), which landed after v0.10.11 (the build in the report). The user should upgrade to ≥ the build containing #600 (main is now 0.10.19). #600 backdates + index-spaces versionTime on both create_did_webvh (genesis) and update_did_webvh, via backdated_version_time.

What this PR adds

#600 shipped with only manual end-to-end validation and no automated regression test. This closes that gap:

  • create_then_didcomm_enable_back_to_back_resolves (did_webvh e2e): drives create → didcomm-enable with no sleep in between (every other e2e test in the module dodges the bug by sleeping past the second boundary), then asserts the chain validates and advertises DIDCommMessaging at version 2. Temporarily neutering backdated_version_time makes it fail with the exact didwebvh-rs error: Current versionTime (...) must be greater than previous versionTime (...). Log truncated at 2-... — proving it's a genuine guard, not a vacuous pass.
  • backdated_version_time_is_past_and_strictly_increasing (unit): pins the helper's contract — timestamps are in the past and strictly increasing by entry index at second precision.

Reuses the shared with_didcomm_service patcher rather than hand-rolling a service-array edit (per workspace CLAUDE.md).

Validation

  • cargo fmt clean
  • cargo clippy -p vta-service --all-targets — no new warnings (2 pre-existing, unrelated, in provision_integration/preconditions.rs)
  • cargo test -p vta-service — all green
  • Bumps vta-service 0.10.18 → 0.10.19

https://claude.ai/code/session_01HoRff8BDqXuSfQ7RNjm3ic

…on (#600)

The VTA creates its did:webvh at `vta setup` and updates it moments later
(e.g. `services didcomm enable` patching in the DIDComm mediator service).
did:webvh serialises versionTime at second granularity and requires each
entry to be strictly later than the previous, so two entries minted in the
same wall-clock second serialise identically and the DID resolves back to
the genesis (REST-only) entry — the operator sees `services didcomm enable`
report success and write config.toml, yet the published DID document still
advertises REST only at version 1.

PR #600 fixed this by backdating + index-spacing versionTime on the
genesis-create and standard-update entries (`backdated_version_time`), but
shipped with only manual end-to-end validation. This adds automated guards:

- A did_webvh e2e test driving create -> didcomm-enable *back-to-back with
  no sleep* (every other e2e test dodges the bug by sleeping past the
  second boundary), asserting the chain still validates and advertises
  DIDCommMessaging at version 2. Neutering `backdated_version_time` makes it
  fail with the exact didwebvh-rs error ("Current versionTime must be
  greater than previous versionTime ... Log truncated at 2-...").
- A unit test pinning `backdated_version_time`'s contract: timestamps are in
  the past and strictly increasing by entry index at second precision.

Reuses the shared `with_didcomm_service` patcher rather than hand-rolling a
service-array edit.

Bumps vta-service 0.10.18 -> 0.10.19.

Claude-Session: https://claude.ai/code/session_01HoRff8BDqXuSfQ7RNjm3ic
Signed-off-by: Glenn Gore <glenn@affinidi.com>
@stormer78
stormer78 requested a review from a team as a code owner July 2, 2026 09:49
@stormer78
stormer78 merged commit 745a9a1 into main Jul 2, 2026
9 of 10 checks passed
@stormer78
stormer78 deleted the worktree-fix-offline-didcomm-enable-republish branch July 2, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant