Skip to content

Beta 0.7.3 REST and adapter contract drift gate

Summary

Prove that native REST, qBittorrent-compatible, and Torznab-compatible surfaces have not drifted from their intended contracts. Native /api/v1 behavior must remain clean and typed; adapter-specific quirks must stay isolated in the qBit and Torznab compatibility layers.

Acceptance Criteria

  • [x] OpenAPI/native REST route manifest matches current implementation.
  • [x] Safe native REST routes pass the contract smoke suite.
  • [x] Destructive native REST routes have explicit confirmation or intent inventory coverage.
  • [x] Native REST malformed input returns typed JSON errors where expected.
  • [x] qBittorrent-compatible auth rejects missing, wrong, and stale sessions.
  • [x] qBittorrent-compatible malformed booleans and hashes are rejected or handled according to the adapter contract.
  • [x] Torznab API key, category, query, and feed behavior is replayed.
  • [x] Adapter error shapes remain adapter-local and do not force native /api/v1 response aliases or envelopes.

Validation

  • python -m emule_workspace test python --path tests\python\test_rest_api_smoke.py --quiet
  • python -m emule_workspace test live-e2e --config Release --platform x64 --suite rest-api

Completion Evidence

  • 2026-05-10 refresh:
  • python -m emule_workspace validate passed after updating the canonical branch-store checkout to app origin/main.
  • python -m emule_workspace build app --config Debug --platform x64 passed after app commit e05054f fixed an ambiguous debug EMFileSize zero check in the protected-volume demand path.
  • python -m emule_workspace build app --config Release --platform x64 passed.
  • python -m emule_workspace test python --path tests\python\test_rest_api_smoke.py --path tests\python\test_release_golden.py --quiet passed: 72 tests.
  • python -m emule_workspace test live-e2e --config Release --platform x64 --suite rest-api --rest-coverage-budget contract-stress --rest-stress-budget smoke --rest-stress-duration-seconds 10 --rest-stress-concurrency 4 --rest-download-trigger-count 3 --skip-live-seed-refresh passed. Artifact: EMULE_WORKSPACE_ROOT\repos\emulebb-build-tests\reports\rest-api-smoke\20260510-235256-eMule-main-release\result.json.
  • Live contract parity recorded openapi_route_count=85, registry_route_count=85, safe_route_count=82, unsafe_route_count=3, exercised_route_count=82, and no failed routes. Strict OpenAPI response-schema validation was active for successful native REST envelopes and typed JSON error envelopes.
  • Route execution reporting recorded direct=1 and ui-thread=84; the only direct native route is GET /api/v1/app.
  • Live stress completed 4181 requests with native_rest_non_json_count=0, timeout_count=0, p95 latency 68.172 ms, and no failure sample.
  • Local dump configuration was enabled for emule.exe, umdh.exe, procdump.exe, and procdump64.exe with dump count 64.
  • Dedicated Prowlarr/Torznab live proof passed: EMULE_WORKSPACE_ROOT\repos\emulebb-build-tests\reports\prowlarr-emulebb-live\20260510-224143-eMule-main-release.
  • Dedicated Radarr/Sonarr plus qBit-compatible live proof passed: EMULE_WORKSPACE_ROOT\repos\emulebb-build-tests\reports\radarr-sonarr-emulebb-live\20260510-224447-eMule-main-release.
  • Dedicated aMuTorrent browser smoke did not reach browser execution: EMULE_WORKSPACE_ROOT\repos\emulebb-build-tests\reports\amutorrent-browser-smoke\20260510-225224-eMule-main-release. eMule REST readiness passed, but aMuTorrent bound to 127.0.0.1:57415 from its persistent server config while the harness waited on the requested generated port 127.0.0.1:55939. Treat this as an aMuTorrent/harness configuration drift follow-up (BUG-102), not a native /api/v1 contract failure.

  • python -m emule_workspace test python --path tests\python\test_rest_api_smoke.py --quiet passed: 63 tests.

  • python -m emule_workspace test live-e2e --config Release --platform x64 --suite rest-api passed. Artifact: EMULE_WORKSPACE_ROOT\repos\emulebb-build-tests\reports\rest-api-smoke\20260509-144340-eMule-main-release\result.json.
  • The live REST contract report recorded OpenAPI and registry parity: openapi_route_count=82, registry_route_count=82, operation_count=82, and no missing or duplicate routes.
  • The contract smoke exercised 81 safe routes with 0 failed routes; /api/v1/app/shutdown remained the single skipped unsafe route.
  • The destructive-route evidence includes the shutdown exclusion audit and expected confirmation/intent coverage for destructive native operations.
  • Native REST malformed-input coverage stayed in the typed JSON error envelope lane; expected negative contract routes reported 45 expected errors and no undeclared failed routes.
  • qBittorrent-compatible adapter probes covered unauthenticated category reads, wrong cookies, bad login, malformed booleans, missing or bad hashes, category filtering, and add/delete/property/file flows.
  • Torznab adapter probes covered unauthenticated and wrong API keys, duplicate query parameters, malformed search input, bad category input, caps, and feed behavior.
  • Adapter error shapes remained adapter-local: qBit responses used qBit-style text/plain outcomes and Torznab responses used XML feed/error behavior rather than native /api/v1 JSON aliases or envelopes.

Relationship To Other Items