Touchstone conformance report

target sut (http://127.0.0.1:41427/lws/harness/) · run 33738dc0 · 2026-10-21T13:18:22.856960779Z

CONFORMANT — no MUST test failed or ended cantTell

221 tests: 210 passed · 0 failed · 0 cantTell · 11 inapplicable (verdict per definitions/EXECUTION.md §9: each test has one level; only MUST tests decide conformance, and SHOULD and MAY failures are advisory. 10 MUST test(s) were inapplicable: coverage this run did not have, not evidence either way.)

Coverage by level

LevelRequirementsCovered by testsWith failures
MUST2142050
SHOULD25200
MAY33180

49 catalog requirements bind only clients, receivers, identity providers or other specifications, which a server run cannot break, so coverage leaves them out. Any that a test here cites as a premise still appear in the matrix.

Requirements matrix

RequirementLevelTestsResult
id-token-alg-not-none MUST auth/oidc/manifest#authn-oidc-alg-none PASS
id-token-aud-claim MUST auth/oidc/manifest#authn-oidc-valid-id-token PASS
id-token-azp-claim MUST auth/oidc/manifest#authn-oidc-valid-id-token auth/oidc/manifest#authn-oidc-missing-azp PASS
id-token-iss-claim MUST auth/oidc/manifest#authn-oidc-valid-id-token PASS
id-token-sub-claim MUST auth/oidc/manifest#authn-oidc-valid-id-token PASS
id-token-token-type-uri MUST auth/oidc/manifest#authn-oidc-valid-id-token PASS
validation-dereference-subject-cid MUST auth/oidc/manifest#authn-oidc-valid-id-token auth/oidc/manifest#authn-oidc-untrusted-issuer PASS
validation-locate-issuer-service-and-verify MUST auth/oidc/manifest#authn-oidc-valid-id-token auth/oidc/manifest#authn-oidc-expired-id-token auth/oidc/manifest#authn-oidc-bad-signature auth/oidc/manifest#authn-oidc-untrusted-issuer PASS
audience-restriction MUST auth/saml/manifest#authn-saml-valid-assertion INAPPLICABLE
issuer-assertion MUST auth/saml/manifest#authn-saml-valid-assertion INAPPLICABLE
nameid-subject MUST auth/saml/manifest#authn-saml-valid-assertion INAPPLICABLE
recipient-client-id MUST auth/saml/manifest#authn-saml-valid-assertion INAPPLICABLE
signed-and-required-assertions MUST auth/saml/manifest#authn-saml-valid-assertion auth/saml/manifest#authn-saml-unsigned INAPPLICABLE
token-type-saml2 MUST auth/saml/manifest#authn-saml-valid-assertion INAPPLICABLE
validation-signature MUST auth/saml/manifest#authn-saml-valid-assertion auth/saml/manifest#authn-saml-invalid-signature INAPPLICABLE
alg-not-none MUST auth/cid/manifest#authn-cid-alg-none auth/cid/manifest#authn-cid-didkey-alg-none PASS
aud-includes-as MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-audience-excludes-as PASS
client-id-claim MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential PASS
exp-claim MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-missing-exp PASS
iat-claim MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-missing-iat PASS
iss-claim MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential PASS
sub-claim MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential PASS
sub-iss-client-same-uri MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-claims-mismatch auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-claims-mismatch auth/cid/manifest#authn-cid-didkey-missing-subject auth/cid/manifest#authn-cid-didkey-missing-issuer auth/cid/manifest#authn-cid-didkey-missing-client-id PASS
token-type-jwt MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-didkey-valid-credential PASS
validation-all-claims MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-claims-mismatch auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-alg-none auth/cid/manifest#authn-cid-didkey-claims-mismatch auth/cid/manifest#authn-cid-didkey-audience-excludes-as auth/cid/manifest#authn-cid-didkey-missing-exp auth/cid/manifest#authn-cid-didkey-missing-iat PASS
validation-dereference-sub-cid MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-document-id-mismatch auth/cid/manifest#authn-cid-referenced-method auth/cid/manifest#authn-cid-didkey-valid-credential PASS
validation-exp-in-future MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-expired auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-expired PASS
validation-kid-verification-method MUST auth/cid/manifest#authn-cid-valid-credential auth/cid/manifest#authn-cid-unknown-kid auth/cid/manifest#authn-cid-bad-signature auth/cid/manifest#authn-cid-key-not-for-authentication auth/cid/manifest#authn-cid-key-revoked auth/cid/manifest#authn-cid-foreign-controller auth/cid/manifest#authn-cid-referenced-method auth/cid/manifest#authn-cid-didkey-valid-credential auth/cid/manifest#authn-cid-didkey-invalid-signature PASS
validation-reject-alg-none MUST auth/cid/manifest#authn-cid-alg-none PASS
access-access-collection MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
access-access-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
access-endpoints-are-lws-containers MUST core/access_grants#access-grant-endpoint-is-container PASS
access-endpoints-get-post-delete SHOULD core/access_grants#access-grant-revoke PASS
access-endpoints-jsonld-payloads MUST core/access_grants#access-grant-create PASS
access-extra-properties-allowed MAY core/access_grants#access-grant-extra-properties-accepted PASS
access-inbox-notifications SHOULD core/access_grants#access-grant-inbox-notified PASS
access-inbox-optional MAY core/access_grants#access-grant-extra-properties-accepted PASS
access-inbox-uri MUST core/access_grants#access-grant-incomplete-refused PASS
access-jsonld-context-lws-v1 MUST core/access_grants#access-grant-document-shape PASS
access-notification-data-model MUST core/access_grants#access-grant-inbox-notified PASS
access-notification-delivery MUST core/access_grants#access-grant-inbox-notified PASS
access-notification-events SHOULD core/access_grants#access-grant-inbox-notified PASS
access-notify-grant-created SHOULD UNCOVERED
access-notify-other-events MAY UNCOVERED
access-notify-request-created SHOULD UNCOVERED
access-post-location-header MUST core/access_grants#access-grant-create core/access_grants#access-request-create PASS
access-services-advertised MUST core/access_grants#access-grant-endpoint-is-container PASS
access-storage-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
access-storage-uri MUST core/access_grants#access-grant-create PASS
access-type-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
access-type-values MUST core/access_grants#access-grant-create core/access_grants#access-request-create PASS
authn-client-claim MUST auth/oidc/manifest#authn-oidc-missing-azp auth/cid/manifest#authn-cid-didkey-missing-client-id PASS
authn-credential-signed MUST auth/oidc/manifest#authn-oidc-alg-none auth/oidc/manifest#authn-oidc-bad-signature auth/cid/manifest#authn-cid-bad-signature auth/cid/manifest#authn-cid-alg-none auth/cid/manifest#authn-cid-didkey-invalid-signature auth/cid/manifest#authn-cid-didkey-alg-none auth/saml/manifest#authn-saml-invalid-signature auth/saml/manifest#authn-saml-unsigned PASS
authn-credential-tamper-evident-claims MUST auth/cid/manifest#authn-cid-didkey-missing-subject auth/cid/manifest#authn-cid-didkey-missing-issuer auth/cid/manifest#authn-cid-didkey-missing-client-id PASS
authn-issuer-claim-uri MUST auth/cid/manifest#authn-cid-didkey-missing-issuer PASS
authn-issuer-trust-out-of-band MAY UNCOVERED
authn-subject-claim-uri MUST auth/cid/manifest#authn-cid-didkey-missing-subject PASS
authn-suite-token-type-uri MUST core/authorization_server#authz-metadata-subject-token-types-are-uris PASS
authz-401-www-authenticate-challenge MUST core/storage_authorization#getContainer-private-unauthorized core/storage_authorization#protected-resource-metadata-data-resource core/storage_authorization#createDataResource-unauthorized core/storage_authorization#updateDataResource-unauthorized core/storage_authorization#deleteDataResource-unauthorized PASS
authz-access-token-aud-claim MUST core/storage_authorization#authz-token-wrong-audience-rejected core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-client-id-claim MUST core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-exp-short-lived MUST core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-iat-claim MUST core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-iss-claim MUST core/storage_authorization#authz-token-wrong-issuer-rejected core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-jti-claim MUST core/authorization_server#authz-token-exchange-valid PASS
authz-access-token-sub-claim MUST core/authorization_server#authz-token-exchange-valid PASS
authz-bearer-presentation-rfc6750 MUST core/storage_authorization#getContainer-authenticated-owner PASS
authz-challenge-extra-params MAY UNCOVERED
authz-client-prm-resource-matches MUST core/storage_authorization#protected-resource-metadata core/storage_authorization#protected-resource-metadata-data-resource PASS
authz-client-resource-metadata-same-origin MUST core/storage_authorization#getContainer-private-unauthorized PASS
authz-client-storage-root-same-origin MUST core/storage_authorization#storage-root-same-origin PASS
authz-invalid-token-401-error-param MUST core/storage_authorization#authz-expired-token-rejected core/storage_authorization#authz-token-bad-signature-rejected PASS
authz-jwt-signature-jwks-rotation MUST core/storage_authorization#authz-token-bad-signature-rejected core/storage_authorization#authz-token-alg-none-rejected core/storage_authorization#authz-token-unknown-key-rejected core/authorization_server#authz-issued-token-accepted-by-storage PASS
authz-metadata-subject-identifier-types SHOULD core/authorization_server#authz-metadata-subject-identifier-types PASS
authz-metadata-subject-token-types SHOULD core/authorization_server#authz-metadata-subject-token-types core/authorization_server#authz-metadata-subject-token-types-are-uris PASS
authz-oauth2-baseline MAY UNCOVERED
authz-policy-denial-rejected MUST core/storage_authorization#authz-non-owner-read-rejected core/storage_authorization#authz-non-owner-write-rejected core/storage_authorization#authz-non-owner-delete-rejected core/access_grants#access-grant-authenticated-agent PASS
authz-prm-authorization-servers MUST core/storage_authorization#protected-resource-metadata PASS
authz-prm-conforms-rfc9728 MUST core/storage_authorization#protected-resource-metadata PASS
authz-server-metadata-well-known MUST core/authorization_server#authz-server-metadata-well-known PASS
authz-token-error-rfc6749 MUST core/authorization_server#authz-token-exchange-invalid-resource core/authorization_server#authz-token-exchange-missing-resource core/authorization_server#authz-token-exchange-missing-subject-token PASS
authz-token-exchange-grant MUST core/authorization_server#authz-server-metadata-well-known core/authorization_server#authz-token-exchange-valid PASS
authz-token-exchange-resource-param MUST core/authorization_server#authz-token-exchange-valid core/authorization_server#authz-token-exchange-invalid-resource core/authorization_server#authz-token-exchange-missing-resource PASS
authz-token-exchange-subject-token-param MUST core/authorization_server#authz-token-exchange-valid core/authorization_server#authz-token-exchange-missing-subject-token PASS
authz-token-response-rfc6749-rfc9068 MUST core/authorization_server#authz-token-exchange-valid PASS
authz-token-validation-checklist MUST core/storage_authorization#getContainer-authenticated-owner core/storage_authorization#authz-expired-token-rejected core/storage_authorization#authz-token-alg-none-rejected core/storage_authorization#authz-token-unknown-key-rejected core/storage_authorization#authz-token-wrong-audience-rejected core/storage_authorization#authz-token-wrong-issuer-rejected core/storage_authorization#authz-token-not-yet-valid-rejected core/storage_authorization#authz-token-issued-in-future-rejected core/authorization_server#authz-issued-token-accepted-by-storage PASS
authz-validate-before-issuing MUST core/authorization_server#authz-token-exchange-valid PASS
capability-move-applies-to MUST core/moving#discovery-move-capability core/moving#move-container core/moving#move-container-refused-without-container-support PASS
capability-move-preserves-identifier MUST core/moving#discovery-move-capability core/moving#move-keeps-identifier-content-and-links PASS
capability-move-resource MUST core/moving#move-data-resource core/moving#move-refused-without-capability PASS
conditional-requests-supported SHOULD core/conditional_requests#conditional-get-304 core/conditional_requests#conditional-delete-stale-if-match-412 core/conditional_requests#conditional-get-if-modified-since-304 core/conditional_requests#conditional-get-if-unmodified-since-412 PASS
conformance-server-class MUST UNCOVERED
conneg-lws-json-honored MUST core/containers#container-conneg core/containers#container-conneg-weighted PASS
conneg-lws-profile-isomorphic MUST core/containers#container-lws-profile-ld-json core/containers#container-lws-profile-turtle PASS
conneg-vary-accept SHOULD core/containers#container-conneg-vary PASS
contained-description-required-members MUST core/containers#getContainer-containmentIntegrity PASS
contained-format-for-dataresources MUST core/containers#getContainer-containmentIntegrity core/containers#contained-resource-format PASS
contained-resource-type-values MUST core/containers#contained-resource-type-values PASS
container-empty-items-array MUST core/containers#createContainer core/containers#getContainer-containmentIntegrity PASS
container-listing-authorization-visibility MUST core/containers#getContainer-containmentIntegrity PASS
container-model-members MAY UNCOVERED
container-representation-required-properties MUST core/containers#getContainer PASS
container-totalitems-accuracy SHOULD core/containers#container-total-items-accurate PASS
containment-create-atomic-items MUST core/containers#getContainer-containmentIntegrity PASS
containment-delete-atomic-items MUST core/containers#delete-empty-container core/data_resources#deleteDataResource core/conditional_requests#delete-updates-parent-strong-etag PASS
containment-integrity MUST core/containers#containment-hierarchy-consistent PASS
containment-integrity-move MUST core/moving#move-data-resource PASS
containment-no-cycles MUST UNCOVERED
containment-no-orphans MUST core/containers#containment-hierarchy-consistent PASS
containment-rel-up-get-head MUST core/containers#getContainer core/data_resources#readDataResource core/data_resources#data-resource-head-parity core/linksets#linkset-up-not-redirected PASS
create-linkset-before-success MUST core/data_resources#createDataResource PASS
create-post-201-location-links MUST core/containers#createContainer core/containers#createContainer-type-link core/data_resources#createDataResource core/data_resources#createDataResource-type-link core/linksets#linkset-ready-at-create PASS
create-post-missing-container-404 MUST core/data_resources#create-in-missing-container-rejected core/data_resources#create-in-missing-container-404 PASS
create-post-not-idempotent SHOULD core/data_resources#create-post-twice-distinct PASS
create-server-managed-metadata-protected MUST core/data_resources#create-server-managed-links-protected PASS
delete-401-403-404-semantics MUST core/storage_authorization#deleteDataResource-unauthorized core/storage_authorization#authz-non-owner-delete-rejected PASS
delete-if-match-optional MAY core/conditional_requests#conditional-delete-stale-if-match-412 PASS
delete-non-empty-container-409-depth MUST core/containers#delete-non-empty-container-409 core/containers#delete-container-recursive core/containers#delete-container-recursive-deep PASS
delete-removes-from-parent-listing MUST core/containers#delete-container-recursive-deep core/conditional_requests#delete-updates-parent-strong-etag PASS
delete-success-204-conditional MUST core/containers#delete-empty-container core/data_resources#deleteDataResource core/conditional_requests#conditional-delete-stale-if-match-412 PASS
error-rfc9457-problem-details SHOULD core/data_resources#error-problem-details PASS
get-data-resource-content-range-etag MUST core/data_resources#createDataResource core/data_resources#readDataResource core/data_resources#data-resource-range-request PASS
head-parity-with-get MUST core/containers#container-head-parity core/data_resources#data-resource-head-parity PASS
linkset-accept-patch-json-patch MUST core/linksets#linkset-advertises-patch PASS
linkset-allow-get-patch MUST core/linksets#linkset-advertises-patch PASS
linkset-etag-get-head MUST core/linksets#getLinkset PASS
linkset-lifecycle-tied-to-resource MUST core/containers#delete-container-recursive-deep core/linksets#linkset-removed-with-resource PASS
linkset-media-type-json MUST core/linksets#getLinkset PASS
linkset-optional-methods-advertised MUST core/linksets#linkset-put-405-when-unsupported PASS
linkset-patch-json-patch MUST core/linksets#linkset-patch-json-patch PASS
linkset-precondition-failed-412 MUST core/linksets#linkset-conditional-412 PASS
linkset-put-405-if-unsupported MUST core/linksets#linkset-put-405-when-unsupported PASS
linkset-server-managed-atomic MUST core/linksets#linkset-removed-with-resource core/linksets#linkset-ready-at-create PASS
linkset-standalone-rfc9264 MUST core/linksets#getLinkset core/linksets#linkset-patch-stays-linkset PASS
lws-cid-media-type-storage-description MUST core/discovery#discovery-storage-description PASS
lws-json-media-type-container-representation MUST core/containers#container-conneg PASS
metadata-capability-advertising MUST core/linksets#linkset-advertises-patch PASS
move-authorization-delete-and-create MUST core/moving#move-needs-create-in-destination core/moving#move-needs-delete-of-resource PASS
move-container-subtree-authorization MUST UNCOVERED
move-containers-applies-to MUST core/moving#move-container core/moving#move-container-refused-without-container-support PASS
move-containment-atomic MUST core/moving#move-data-resource core/moving#move-updates-container-etags core/moving#move-container PASS
move-containment-integrity-cycles MUST core/moving#move-container-into-itself-refused PASS
move-cross-storage-may-reject MAY UNCOVERED
move-destination-existing-container MUST core/linksets#linkset-up-not-redirected core/moving#move-invalid-destination-refused PASS
move-identifier-preserved MUST core/moving#move-keeps-identifier-content-and-links INAPPLICABLE
move-new-identifier-response MUST UNCOVERED
move-notification-single-activity SHOULD core/moving#move-notification PASS
move-request-json-patch MUST core/moving#move-data-resource PASS
move-server-support MUST core/linksets#linkset-up-not-redirected core/moving#move-data-resource core/moving#move-refused-without-capability PASS
notification-activity-as2-conformance MUST core/notifications#notification-delivered-create PASS
notification-activity-id MUST core/notifications#notification-delivered-create PASS
notification-activity-move MUST core/moving#move-notification PASS
notification-activity-object MUST core/notifications#notification-delivered-create PASS
notification-activity-object-id MUST core/notifications#notification-delivered-create core/notifications#notification-delivered-update core/notifications#notification-delivered-delete core/notifications#notification-delivered-in-subcontainer core/notifications#notification-scope-data-resource-only PASS
notification-activity-object-type MUST core/notifications#notification-delivered-create PASS
notification-activity-optional-properties MAY core/notifications#notification-actor-omitted PASS
notification-activity-published MUST core/notifications#notification-delivered-create PASS
notification-activity-type MUST core/notifications#notification-delivered-create core/notifications#notification-delivered-update core/notifications#notification-delivered-delete PASS
notification-activity-types-additional MAY UNCOVERED
notification-activity-types-supported MUST core/notifications#notification-delivered-create core/notifications#notification-delivered-update core/notifications#notification-delivered-delete core/notifications#notification-delivered-in-subcontainer core/notifications#notification-scope-data-resource-only PASS
notification-batching MAY UNCOVERED
notification-envelope-activity MUST core/notifications#notification-delivered-create PASS
notification-envelope-storage MUST core/notifications#notification-delivered-create PASS
notification-envelope-type MUST core/notifications#notification-delivered-create PASS
notification-suite-subscription-type-identifier MUST core/notifications#subscription-create PASS
notifications-advertise-notificationservice MUST core/notifications#notification-service-advertised PASS
notificationservice-additional-properties MAY UNCOVERED
notificationservice-endpoint-and-subscription-types MUST core/notifications#notification-service-advertised PASS
operations-core-four-atomic MUST UNCOVERED
pagination-200-totalitems-all-pages MUST core/pagination#pagination-first-page core/pagination#pagination-next-page core/pagination#pagination-totalitems-all-pages PASS
pagination-first-page-flow MAY core/pagination#pagination-first-page PASS
pagination-over-threshold SHOULD UNCOVERED
patch-json-patch-baseline MUST core/data_resources#patch-json-patch-baseline core/data_resources#patch-json-patch-atomic PASS
policy-action-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
policy-action-values MUST core/access_grants#access-grant-authenticated-agent PASS
policy-assignee-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
policy-assignee-uri-foaf-agent MUST core/access_grants#getContainer-public-read core/access_grants#readDataResource-public-read PASS
policy-constraint-left-operands MUST core/access_grants#access-grant-constraints-all-satisfied core/access_grants#access-grant-left-operands-accepted core/access_grants#access-grant-constraint-format core/access_grants#access-grant-constraint-type core/access_grants#access-grant-constraint-client PASS
policy-constraint-objects MUST core/access_grants#access-grant-constraints-all-satisfied core/access_grants#access-grant-left-operands-accepted PASS
policy-constraint-optional MAY core/access_grants#access-grant-extra-properties-accepted PASS
policy-constraints-all-satisfied MUST core/access_grants#access-grant-constraints-all-satisfied PASS
policy-constraints-conjunction-semantics MUST core/access_grants#access-grant-constraints-all-satisfied PASS
policy-target-extra-types MAY UNCOVERED
policy-target-object MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
policy-target-optional MAY UNCOVERED
policy-type-access-policy MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
policy-type-required MUST core/access_grants#access-grant-document-shape core/access_grants#access-grant-incomplete-refused PASS
privacy-move-redirect-access-control SHOULD UNCOVERED
privacy-notification-actor-omitted SHOULD core/notifications#notification-actor-omitted PASS
privacy-notification-authorized-resources-only SHOULD core/notifications#notification-not-delivered-for-unreadable-resource INAPPLICABLE
put-clients-use-conditional-requests SHOULD UNCOVERED
read-container-listing-authz-filtered MAY core/access_grants#container-listing-filtered-metadata PASS
read-container-listing-member-metadata MUST core/containers#contained-resource-format PASS
security-move-capability-restraint MUST UNCOVERED
security-move-container-subtree MUST UNCOVERED
security-move-privilege-combination MUST core/moving#move-needs-create-in-destination core/moving#move-needs-delete-of-resource PASS
security-notification-access-control MUST core/notifications#subscription-unreadable-topic-refused core/notifications#subscription-after-revocation-refused core/notifications#notification-not-delivered-for-unreadable-resource core/notifications#notification-stops-after-revocation PASS
status-204-410-deletions MAY core/data_resources#deleteDataResource PASS
storage-capability-id-optional MUST core/discovery#discovery-storage-description-ids-are-uris PASS
storage-capability-property MUST core/discovery#discovery-storage-description-ids-are-uris PASS
storage-capability-type-required MUST core/discovery#discovery-storage-description PASS
storage-description-id-required MUST core/discovery#discovery-storage-description PASS
storage-description-lws-cid MUST core/discovery#discovery-storage-description PASS
storage-description-storageroot-service MUST core/discovery#discovery-storage-description core/discovery#discovery-storage-root-is-container PASS
storage-description-type-storage MUST core/discovery#discovery-storage-description PASS
storage-service-endpoint-required MUST core/discovery#discovery-storage-description PASS
storage-service-id-optional MUST core/discovery#discovery-storage-description-ids-are-uris PASS
storage-service-property MUST core/discovery#discovery-storage-description PASS
storage-service-type-required MUST core/discovery#discovery-storage-description PASS
storage-uri-returns-lws-cid-document MUST core/discovery#discovery-storage-description core/discovery#discovery-storage-description-default-media-type PASS
subscription-authorization-on-create MUST core/notifications#subscription-unreadable-topic-refused core/notifications#subscription-after-revocation-refused PASS
subscription-authorization-on-delivery MUST core/notifications#notification-not-delivered-for-unreadable-resource core/notifications#notification-stops-after-revocation PASS
subscription-authorization-revoked MUST core/notifications#notification-stops-after-revocation PASS
subscription-create-post-lws-json MUST core/notifications#subscription-create PASS
subscription-request-additional-fields MAY core/notifications#subscription-create PASS
subscription-request-required-fields MUST core/notifications#subscription-create core/notifications#subscription-missing-type-refused core/notifications#subscription-missing-topic-refused PASS
subscription-request-topic MUST core/notifications#subscription-create core/notifications#subscription-missing-topic-refused PASS
subscription-request-type MUST core/notifications#subscription-create core/notifications#subscription-missing-type-refused core/notifications#subscription-unadvertised-type-refused PASS
subscription-response-lws-json MUST core/notifications#subscription-create PASS
subscription-response-subscription-url MUST core/notifications#subscription-create PASS
subscription-response-type MUST core/notifications#subscription-create PASS
update-content-vs-metadata-prefer-set-linkset MUST core/data_resources#updateDataResource PASS
uri-independent-of-hierarchy SHOULD core/data_resources#create-post-twice-distinct PASS
accept-query-advertised SHOULD index/manifest#type-search-accept-query-advertised PASS
accept-query-no-disclosure MUST index/manifest#type-search-accept-query-advertised PASS
at-members-ignored MUST index/manifest#type-search-at-members-ignored PASS
authorization-enforced MUST index/manifest#type-index-lists-readable-types index/manifest#type-index-omits-unreadable-type index/manifest#type-search-authorization-filtered PASS
baseline-format-supported MUST index/manifest#type-search-by-type PASS
consistency-not-for-authorization MUST index/manifest#type-search-revoked-not-shown PASS
content-location-protected MUST index/manifest#type-search-content-location-protected INAPPLICABLE
content-types-identical MUST index/manifest#type-search-content-types-identical PASS
counts-filtered MUST index/manifest#type-search-authorization-filtered PASS
current-authorization MUST index/manifest#type-search-revoked-not-shown PASS
derived-index-filtered MUST index/manifest#type-search-authorization-filtered index/manifest#type-search-revoked-not-shown PASS
duplicate-groups-ignored MUST index/manifest#type-search-duplicate-groups PASS
empty-group-rejected MUST index/manifest#type-search-empty-group-rejected PASS
eventually-consistent MAY UNCOVERED
expired-page-404-410 MUST index/manifest#type-search-unrecognized-page-link INAPPLICABLE
extensions-uphold-authorization MUST UNCOVERED
grammar-not-extended MUST index/manifest#type-search-bad-element-rejected PASS
invalid-iri-400 MUST index/manifest#type-search-relative-iri-rejected PASS
malformed-filter-400 MUST index/manifest#type-search-empty-group-rejected index/manifest#type-search-type-not-array-rejected index/manifest#type-search-bad-element-rejected index/manifest#type-search-malformed-json-rejected PASS
missing-content-type-400 MUST index/manifest#type-search-missing-content-type-rejected PASS
no-existence-disclosure MUST index/manifest#type-index-omits-unreadable-type index/manifest#type-search-authorization-filtered PASS
no-match-not-error MUST index/manifest#type-search-no-match index/manifest#type-search-unindexed-relation PASS
no-shared-cache MUST index/manifest#type-index-not-shared index/manifest#type-search-not-shared PASS
no-silent-narrowing MUST index/manifest#type-search-too-complex PASS
not-acceptable-406 MUST index/manifest#type-search-not-acceptable PASS
other-formats MAY UNCOVERED
other-response-formats MAY index/manifest#type-search-vary-accept PASS
query-content-type-required MUST index/manifest#type-search-missing-content-type-rejected PASS
query-safe-idempotent MAY index/manifest#type-search-safe PASS
reflect-change-bounded SHOULD index/manifest#type-index-lists-readable-types index/manifest#type-search-by-type index/manifest#type-search-reflects-update index/manifest#type-search-reflects-delete PASS
relation-sources-identical MUST index/manifest#type-search-relation-from-link-header PASS
relations-may-be-indexed MAY index/manifest#type-search-unindexed-relation index/manifest#type-search-relation-filter index/manifest#type-search-relation-cnf index/manifest#type-search-relation-from-link-header PASS
relations-not-enumerated MUST UNCOVERED
responses-private MUST index/manifest#type-index-not-shared index/manifest#type-search-not-shared PASS
result-item-id-type MUST index/manifest#type-search-by-type index/manifest#type-search-next-page PASS
result-item-metadata MAY UNCOVERED
revoked-not-shown MUST index/manifest#type-search-revoked-not-shown PASS
search-default-containerpage MUST index/manifest#type-search-by-type index/manifest#type-search-no-match index/manifest#type-search-not-acceptable index/manifest#type-search-next-page PASS
service-advertised MUST index/manifest#index-services-advertised PASS
service-endpoint MUST index/manifest#index-services-advertised PASS
service-extra-properties MAY UNCOVERED
services-optional MAY index/manifest#index-services-advertised PASS
structural-relations-not-indexed MUST index/manifest#type-search-structural-relation-not-indexed PASS
too-complex-422 MUST index/manifest#type-search-too-complex PASS
type-filter MAY index/manifest#type-search-by-type index/manifest#type-search-and-or index/manifest#type-search-native-classes index/manifest#type-search-empty-key-absent index/manifest#type-search-relation-cnf PASS
type-key-supported MUST index/manifest#type-search-by-type index/manifest#type-search-and-or index/manifest#type-search-native-classes PASS
types-from-content MAY index/manifest#type-search-type-from-content PASS
unauthorized-omitted MUST index/manifest#type-index-omits-unreadable-type index/manifest#type-search-authorization-filtered PASS
unindexed-relation-indistinguishable MUST index/manifest#type-search-unindexed-relation index/manifest#type-search-structural-relation-not-indexed PASS
unsupported-format-415 MUST index/manifest#type-search-unsupported-format-rejected PASS
unsupported-format-accept-query SHOULD index/manifest#type-search-unsupported-format-accept-query PASS
vary-accept MUST index/manifest#type-search-vary-accept PASS
delivery-deactivation-optional MAY notifications/webhook/manifest#webhook-subscription-deactivated PASS
delivery-lws-json MUST notifications/webhook/manifest#webhook-delivery-lws-json PASS
delivery-retry-optional MAY notifications/webhook/manifest#webhook-delivery-retried PASS
delivery-signed SHOULD notifications/webhook/manifest#webhook-delivery-signed PASS
inbox-verifies-signature MUST notifications/webhook/manifest#webhook-signature-verifies PASS
keyid-url-with-fragment MUST notifications/webhook/manifest#webhook-signing-key-published PASS
receiver-verification-steps MUST notifications/webhook/manifest#webhook-signature-verifies PASS
response-expires-optional MAY notifications/webhook/manifest#webhook-subscription-expires-supported PASS
response-type-webhook MUST notifications/webhook/manifest#webhook-subscription-response PASS
signature-covered-components MUST notifications/webhook/manifest#webhook-signature-components notifications/webhook/manifest#webhook-signature-verifies PASS
signature-input-created-keyid MUST notifications/webhook/manifest#webhook-signature-components notifications/webhook/manifest#webhook-signing-key-published PASS
signing-key-published MUST notifications/webhook/manifest#webhook-signing-key-published notifications/webhook/manifest#webhook-signature-verifies PASS
storage-description-id-matches MUST notifications/webhook/manifest#webhook-signing-key-published PASS
subscription-expires-optional MAY notifications/webhook/manifest#webhook-subscription-expires-supported PASS
subscription-get-delete MUST notifications/webhook/manifest#webhook-subscription-get-delete PASS
subscription-inbox-required MUST notifications/webhook/manifest#webhook-subscription-response PASS
subscription-listing-container MUST notifications/webhook/manifest#webhook-subscription-listed notifications/webhook/manifest#webhook-subscription-get-delete PASS
subscription-type-and-fields MUST notifications/webhook/manifest#webhook-subscription-response notifications/webhook/manifest#webhook-subscription-expires-supported PASS
subscription-type-identifier MUST notifications/webhook/manifest#webhook-subscription-response PASS

Test results

passed MUST core/discovery#discovery-storage-description 39 ms

The storage URI serves a controlled identifier document describing the storage

verifies: storage-uri-returns-lws-cid-document, storage-description-lws-cid, lws-cid-media-type-storage-description, storage-description-id-required, storage-description-type-storage, storage-service-property, storage-service-type-required, storage-service-endpoint-required, storage-description-storageroot-service, storage-capability-type-required

passed MUST core/discovery#discovery-storage-description-default-media-type 38 ms

Without content negotiation the storage URI answers application/lws+cid

verifies: storage-uri-returns-lws-cid-document

passed MUST core/discovery#discovery-unauthorized-response-headers 38 ms

A 401 from a protected resource links to the storage

verifies: authz-401-storage-link, create-401-storage-link

passed MUST core/discovery#discovery-storage-root-is-container 44 ms

The storage description's StorageRoot service is a container

verifies: storage-description-storageroot-service

passed MUST core/discovery#discovery-storage-description-ids-are-uris 38 ms

Optional service and capability ids in the storage description are URIs

verifies: storage-service-id-optional, storage-capability-id-optional, storage-capability-property

passed MUST core/containers#getContainer 38 ms

Reading a container returns its listing with an ETag and the required links

verifies: read-container-etag-type-links, read-type-distinction-metadata-links, containment-rel-up-get-head, container-representation-required-properties, link-storage-on-responses

passed MUST core/containers#createContainer 43 ms

POST with a Container type link creates an empty container

verifies: create-container-type-link, create-post-201-location-links, container-empty-items-array

passed MUST core/containers#getContainer-containmentIntegrity 47 ms

A created resource appears in its container's listing with its required members

verifies: containment-create-atomic-items, container-listing-authorization-visibility, contained-description-required-members, contained-format-for-dataresources, container-empty-items-array

passed SHOULD core/containers#container-total-items-accurate 59 ms

totalItems tracks the members as they are created and deleted

verifies: container-totalitems-accuracy

passed MUST core/containers#contained-resource-type-values 55 ms

Listings type each member as a Container or a DataResource

verifies: contained-resource-type-values

passed MUST core/containers#contained-resource-format 47 ms

Listings give each data resource member its media type as format

verifies: contained-format-for-dataresources, read-container-listing-member-metadata

passed SHOULD core/containers#contained-resource-size-modified 43 ms

Listings give a data resource member its size in bytes and a modified time

verifies: contained-description-recommended-members

passed MUST core/containers#container-conneg 19 ms

A container asked for as application/lws+json answers as application/lws+json

verifies: conneg-lws-json-honored, lws-json-media-type-container-representation

passed SHOULD core/containers#container-conneg-vary 21 ms

Container responses say that they vary by Accept

verifies: conneg-vary-accept

passed MUST core/containers#container-conneg-weighted 17 ms

A container honours application/lws+json when the Accept header ranks it below a type it cannot serve

verifies: conneg-lws-json-honored

passed MUST core/containers#container-head-parity 41 ms

HEAD of a container returns GET's headers without a body

verifies: head-parity-with-get

passed MUST core/containers#delete-empty-container 32 ms

Deleting an empty container returns 204 and removes it from its parent

verifies: delete-success-204-conditional, containment-delete-atomic-items

passed MUST core/containers#delete-non-empty-container-409 46 ms

A non-recursive DELETE of a non-empty container is refused with 409 and deletes nothing

verifies: delete-non-empty-container-409-depth

passed MAY core/containers#delete-container-recursive 40 ms

Where supported, DELETE with Depth infinity removes a container and its contents

verifies: delete-non-empty-container-409-depth

passed MAY core/containers#delete-container-recursive-deep 39 ms

Where supported, a recursive DELETE removes a whole tree, its linksets, and its listing entry

verifies: delete-non-empty-container-409-depth, linkset-lifecycle-tied-to-resource, delete-removes-from-parent-listing

passed MUST core/containers#containment-hierarchy-consistent 5 ms

Down a nested chain, each resource's up link names its container and each container lists it

verifies: containment-integrity, containment-no-orphans

passed MUST core/containers#container-lws-profile-ld-json 69 ms

A container asked for as JSON-LD in the LWS profile answers with the same RDF as application/lws+json

verifies: conneg-lws-profile-isomorphic

passed MUST core/containers#container-lws-profile-turtle 5 ms

A container asked for as Turtle in the LWS profile answers with the same RDF as application/lws+json

verifies: conneg-lws-profile-isomorphic

passed MUST core/data_resources#createDataResource 29 ms

POST to a container creates a data resource with Location and the server-managed links

verifies: create-post-201-location-links, create-linkset-before-success, get-data-resource-content-range-etag

passed SHOULD core/data_resources#create-post-twice-distinct 38 ms

Two identical POSTs create two resources, at distinct URIs

verifies: create-post-not-idempotent, uri-independent-of-hierarchy

passed MUST core/data_resources#create-in-missing-container-rejected 19 ms

POST to a container that does not exist is refused and creates nothing

verifies: create-post-missing-container-404

passed SHOULD core/data_resources#create-in-missing-container-404 14 ms

POST to a container that does not exist yields 404

verifies: create-post-missing-container-404

passed MUST core/data_resources#readDataResource 29 ms

Reading a data resource returns its content, media type, ETag and the required links

verifies: get-data-resource-content-range-etag, read-type-distinction-metadata-links, containment-rel-up-get-head, link-up-on-non-root-resources, link-storage-on-responses

passed MUST core/data_resources#data-resource-head-parity 30 ms

HEAD of a data resource returns GET's headers without a body

verifies: head-parity-with-get, containment-rel-up-get-head

passed MUST core/data_resources#data-resource-range-request 31 ms

A data resource serves byte ranges with 206

verifies: get-data-resource-content-range-etag

passed SHOULD core/data_resources#data-resource-range-unsatisfiable 27 ms

A range beyond the end of a data resource is answered 416

passed MAY core/data_resources#data-resource-accept-ranges 27 ms

A data resource advertises byte ranges with Accept-Ranges

passed MUST core/data_resources#updateDataResource 36 ms

PUT replaces a data resource's content, answering 200 or 204

verifies: update-content-vs-metadata-prefer-set-linkset

passed MUST core/data_resources#patch-json-patch-baseline 39 ms

PATCH applies JSON Patch to a JSON data resource

verifies: patch-json-patch-baseline

passed MUST core/data_resources#patch-json-patch-atomic 32 ms

A JSON Patch whose test operation fails changes nothing

verifies: patch-json-patch-baseline

passed MUST core/data_resources#deleteDataResource 32 ms

DELETE removes a data resource with 204 and takes it out of its container

verifies: delete-success-204-conditional, containment-delete-atomic-items, status-204-410-deletions

passed SHOULD core/data_resources#post-to-non-container-405 32 ms

POST to a data resource is refused with 405 and an Allow header

passed SHOULD core/data_resources#error-problem-details 16 ms

An error response carries RFC 9457 problem details

verifies: error-rfc9457-problem-details

passed SHOULD core/conditional_requests#conditional-get-304 32 ms

An unchanged data resource answers a conditional GET with 304

verifies: conditional-requests-supported

passed SHOULD core/conditional_requests#conditional-get-container-304 19 ms

An unchanged container listing answers a conditional GET with 304

passed MUST core/conditional_requests#conditional-get-stale-validator-200 39 ms

A conditional GET yields 304 only when the validator still matches

passed MUST core/conditional_requests#conditional-put-stale-if-match-412 45 ms

A PUT carrying a stale entity tag is refused with 412 and changes nothing

passed SHOULD core/conditional_requests#conditional-delete-stale-if-match-412 37 ms

A DELETE carrying a stale entity tag is refused with 412 and deletes nothing

verifies: delete-if-match-optional, delete-success-204-conditional, conditional-requests-supported

passed MUST core/conditional_requests#update-changes-strong-etag 36 ms

A strong entity tag changes when the content changes

passed MUST core/conditional_requests#delete-updates-parent-strong-etag 34 ms

A container's strong entity tag changes when a member is deleted

verifies: containment-delete-atomic-items, delete-removes-from-parent-listing

passed SHOULD core/conditional_requests#conditional-get-if-modified-since-304 34 ms

An unchanged data resource answers If-Modified-Since with 304, a changed one with 200

verifies: conditional-requests-supported

passed SHOULD core/conditional_requests#conditional-get-if-unmodified-since-412 34 ms

If-Unmodified-Since passes at the resource's Last-Modified and fails with 412 before it

verifies: conditional-requests-supported

passed MUST core/linksets#getLinkset 42 ms

The linkset a resource advertises is served as application/linkset+json with an ETag

verifies: linkset-standalone-rfc9264, linkset-media-type-json, linkset-etag-get-head

passed MUST core/linksets#linkset-advertises-patch 34 ms

A linkset advertises GET and PATCH in Allow and JSON Patch in Accept-Patch

verifies: linkset-allow-get-patch, linkset-accept-patch-json-patch, metadata-capability-advertising

passed MUST core/linksets#linkset-conditional-412 36 ms

A linkset PATCH with a failing precondition is refused with 412

verifies: linkset-precondition-failed-412

passed MUST core/linksets#linkset-put-405-when-unsupported 37 ms

A linkset that does not advertise PUT refuses it with 405

verifies: linkset-put-405-if-unsupported, linkset-optional-methods-advertised

passed MUST core/linksets#linkset-removed-with-resource 36 ms

Deleting a resource removes its linkset

verifies: linkset-lifecycle-tied-to-resource, linkset-server-managed-atomic

passed MUST core/linksets#linkset-ready-at-create 28 ms

The linkset a create names exists as soon as the resource does

verifies: linkset-server-managed-atomic, create-post-201-location-links

passed MUST core/linksets#linkset-up-not-redirected 35 ms

Editing a linkset cannot make a resource's rel="up" name anything but its parent

verifies: move-server-support, move-destination-existing-container, containment-rel-up-get-head

passed MUST core/linksets#linkset-patch-stays-linkset 34 ms

A patch that would break the linkset document leaves a valid linkset behind

verifies: linkset-standalone-rfc9264

passed SHOULD core/linksets#linkset-patch-json-patch 42 ms

A JSON Patch adds a user-managed link to a linkset

verifies: linkset-patch-json-patch

passed MUST core/moving#discovery-move-capability 20 ms

A MoveResource capability's appliesTo and preservesIdentifier are well formed

verifies: capability-move-applies-to, capability-move-preserves-identifier

passed MUST core/moving#move-data-resource 76 ms

Patching a data resource's up link moves it to the other container

verifies: move-server-support, move-request-json-patch, move-containment-atomic, containment-integrity-move, capability-move-resource

passed MUST core/moving#move-updates-container-etags 84 ms

A move changes the ETag of the container left and of the container joined

verifies: move-containment-atomic

passed MUST core/moving#move-invalid-destination-refused 71 ms

A move to anything but an existing container, or away from every container, is refused

verifies: move-destination-existing-container

passed MUST core/moving#move-container 86 ms

A storage that moves containers moves one, with what it holds

verifies: move-containers-applies-to, capability-move-applies-to, move-containment-atomic

passed MUST core/moving#move-container-into-itself-refused 66 ms

A container cannot be moved into itself or into a container it holds

verifies: move-containment-integrity-cycles

inapplicable MUST core/moving#move-container-refused-without-container-support 28 ms

A storage whose MoveResource leaves out Container refuses to move a container

verifies: move-containers-applies-to, capability-move-applies-to

core/moving#move-container-refused-without-container-support - inapplicable [MUST] (28 ms)
  inapplicable: precondition 'the storage moves data resources but not containers (otherwise this test does not apply)' does not hold: json /capability some expected some element satisfies [{"pointer":"/type","hasValue":"MoveResource"},{"pointer":"/appliesTo","optional":true,"none":[{"pointer":"","matches":"^(https://www\\.w3\\.org/ns/lws#)?Container$"}]}], got [{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}]
  step 'the storage moves data resources but not containers (otherwise this test does not apply)':
    FAILED json /capability some
      expected: some element satisfies [{"pointer":"/type","hasValue":"MoveResource"},{"pointer":"/appliesTo","optional":true,"none":[{"pointer":"","matches":"^(https://www\\.w3\\.org/ns/lws#)?Container$"}]}]
      actual:   [{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}]
    exchange: GET http://127.0.0.1:41427/lws/ -> 200
    response body: {"@context":["https://www.w3.org/ns/cid/v1","https://www.w3.org/ns/lws/v1"],"id":"http://127.0.0.1:41427/lws/","type":"Storage","verificationMethod":[{"id":"http://127.0.0.1:41427/lws/#key-mvi512e4","type":"JsonWebKey","controller":"http://127.0.0.1:41427/lws/","publicKeyJwk":{"kid":"key-mvi512e4","alg":"ES256","kty":"EC","x":"mWuVksMzeVvrG4aUOEKOiI7S2PDfx3LYm5_YzgNwLSs","y":"6ON_IRez2l6wpreumnxiIi7L_1U6Ru100IoRbWGrD54","crv":"P-256"}}],"authentication":["http://127.0.0.1:41427/lws/#key-mvi512e4"],"capability":[{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}],"service":[{"type":"StorageRoot","serviceEndpoint":"http://127.0.0.1:41427/lws/"},{"type":"NotificationService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/subscriptions","subscriptionType":["WebhookSubscription"]},{"type":"TypeIndexService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/types/index"},{"type":"TypeSearchService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/types/search"},{"type":"AccessRequestService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/access/requests","conformsTo":["https://www.w3.org/ns/lws#AccessProfile"]},{"type":"AccessGrantService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/access/grants","conformsTo":["https://www.w3.org/ns/lws#AccessProfile"]}]}

inapplicable MUST core/moving#move-refused-without-capability 31 ms

A storage that describes no MoveResource capability refuses to move a resource

verifies: move-server-support, capability-move-resource

core/moving#move-refused-without-capability - inapplicable [MUST] (31 ms)
  inapplicable: precondition 'the storage describes no MoveResource capability (otherwise this test does not apply)' does not hold: json /capability none expected none element satisfies [{"pointer":"/type","hasValue":"MoveResource"}], got [{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}]
  step 'the storage describes no MoveResource capability (otherwise this test does not apply)':
    FAILED json /capability none
      expected: none element satisfies [{"pointer":"/type","hasValue":"MoveResource"}]
      actual:   [{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}]
    exchange: GET http://127.0.0.1:41427/lws/ -> 200
    response body: {"@context":["https://www.w3.org/ns/cid/v1","https://www.w3.org/ns/lws/v1"],"id":"http://127.0.0.1:41427/lws/","type":"Storage","verificationMethod":[{"id":"http://127.0.0.1:41427/lws/#key-mvi512e4","type":"JsonWebKey","controller":"http://127.0.0.1:41427/lws/","publicKeyJwk":{"kid":"key-mvi512e4","alg":"ES256","kty":"EC","x":"mWuVksMzeVvrG4aUOEKOiI7S2PDfx3LYm5_YzgNwLSs","y":"6ON_IRez2l6wpreumnxiIi7L_1U6Ru100IoRbWGrD54","crv":"P-256"}}],"authentication":["http://127.0.0.1:41427/lws/#key-mvi512e4"],"capability":[{"type":"MoveResource","appliesTo":["DataResource","Container"],"preservesIdentifier":false}],"service":[{"type":"StorageRoot","serviceEndpoint":"http://127.0.0.1:41427/lws/"},{"type":"NotificationService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/subscriptions","subscriptionType":["WebhookSubscription"]},{"type":"TypeIndexService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/types/index"},{"type":"TypeSearchService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/types/search"},{"type":"AccessRequestService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/access/requests","conformsTo":["https://www.w3.org/ns/lws#AccessProfile"]},{"type":"AccessGrantService","serviceEndpoint":"http://127.0.0.1:41427/lws/-/access/grants","conformsTo":["https://www.w3.org/ns/lws#AccessProfile"]}]}

passed MUST core/moving#move-needs-create-in-destination 70 ms

An agent who may not create in the destination cannot move a resource there

verifies: move-authorization-delete-and-create, security-move-privilege-combination

passed MUST core/moving#move-needs-delete-of-resource 69 ms

An agent who may not delete a resource cannot move it

verifies: move-authorization-delete-and-create, security-move-privilege-combination

passed MUST core/moving#move-notification 2,066 ms

A move is announced as one Move activity from the container left to the container joined

verifies: notification-activity-move, move-notification-single-activity

passed MUST core/storage_authorization#getContainer-private-unauthorized 15 ms

An anonymous request for a protected container is refused with 401 and a conforming challenge

verifies: authz-401-www-authenticate-challenge, authz-client-resource-metadata-same-origin

passed MUST core/storage_authorization#protected-resource-metadata 16 ms

The challenge's resource_metadata is the protected resource metadata of the container requested

verifies: authz-prm-conforms-rfc9728, authz-prm-authorization-servers, authz-client-prm-resource-matches

passed MUST core/storage_authorization#protected-resource-metadata-data-resource 28 ms

A data resource's challenge names protected resource metadata of its own

verifies: authz-401-www-authenticate-challenge, authz-client-prm-resource-matches

passed MUST core/storage_authorization#storage-root-same-origin 26 ms

The storage a 401 links to has its storage root on the requested URI's origin

verifies: authz-client-storage-root-same-origin, authz-401-storage-link

passed MUST core/storage_authorization#getContainer-authenticated-owner 19 ms

The owner's valid access token reads the protected container

verifies: authz-bearer-presentation-rfc6750, authz-token-validation-checklist

passed MUST core/storage_authorization#createDataResource-unauthorized 25 ms

An anonymous POST is refused with 401 and creates nothing

verifies: authz-401-www-authenticate-challenge

passed MUST core/storage_authorization#updateDataResource-unauthorized 39 ms

An anonymous PUT is refused with 401 and changes nothing

verifies: authz-401-www-authenticate-challenge

passed MUST core/storage_authorization#deleteDataResource-unauthorized 37 ms

An anonymous DELETE is refused with 401 and deletes nothing

verifies: delete-401-403-404-semantics, authz-401-www-authenticate-challenge

passed MUST core/storage_authorization#authz-non-owner-read-rejected 19 ms

A valid token without read permission is refused, not challenged

verifies: authz-policy-denial-rejected

passed MUST core/storage_authorization#authz-non-owner-write-rejected 44 ms

A valid token without write permission can neither replace nor create

verifies: authz-policy-denial-rejected

passed MUST core/storage_authorization#authz-non-owner-delete-rejected 33 ms

A valid token without permission cannot delete, and gets 403

verifies: delete-401-403-404-semantics, authz-policy-denial-rejected

passed MUST core/storage_authorization#authz-expired-token-rejected 23 ms

An expired access token is refused with 401 and error invalid_token

verifies: authz-token-validation-checklist, authz-invalid-token-401-error-param

passed MUST core/storage_authorization#authz-token-bad-signature-rejected 15 ms

An access token with a corrupted signature is refused with 401 and invalid_token

verifies: authz-jwt-signature-jwks-rotation, authz-invalid-token-401-error-param

passed MUST core/storage_authorization#authz-token-alg-none-rejected 70 ms

An unsigned (alg none) access token is refused with 401 and invalid_token

verifies: authz-jwt-signature-jwks-rotation, authz-token-validation-checklist

passed MUST core/storage_authorization#authz-token-unknown-key-rejected 16 ms

An access token signed by a key the issuer never published is refused

verifies: authz-jwt-signature-jwks-rotation, authz-token-validation-checklist

passed MUST core/storage_authorization#authz-token-wrong-audience-rejected 14 ms

An access token minted for another storage is refused

verifies: authz-token-validation-checklist, authz-access-token-aud-claim

passed MUST core/storage_authorization#authz-token-wrong-issuer-rejected 11 ms

An access token from an untrusted issuer is refused

verifies: authz-token-validation-checklist, authz-access-token-iss-claim

passed MUST core/storage_authorization#authz-token-not-yet-valid-rejected 13 ms

An access token whose nbf lies in the future is refused

verifies: authz-token-validation-checklist

passed MUST core/storage_authorization#authz-token-issued-in-future-rejected 15 ms

An access token whose iat lies in the future is refused

verifies: authz-token-validation-checklist

passed MUST core/authorization_server#authz-server-metadata-well-known 11 ms

The authorization server publishes RFC 8414 metadata at lws-configuration

verifies: authz-server-metadata-well-known, authz-token-exchange-grant

passed SHOULD core/authorization_server#authz-metadata-subject-token-types 12 ms

The metadata advertises the subject token types it accepts

verifies: authz-metadata-subject-token-types

passed MUST core/authorization_server#authz-metadata-subject-token-types-are-uris 11 ms

Every subject token type the metadata advertises is a URI

verifies: authn-suite-token-type-uri, authz-metadata-subject-token-types

passed SHOULD core/authorization_server#authz-metadata-subject-identifier-types 13 ms

The metadata advertises the subject identifier types it accepts

verifies: authz-metadata-subject-identifier-types

passed MUST core/authorization_server#authz-token-exchange-valid 25 ms

Token exchange issues an RFC 9068 access token for the storage

verifies: authz-token-exchange-grant, authz-token-exchange-resource-param, authz-token-exchange-subject-token-param, authz-validate-before-issuing, authz-token-response-rfc6749-rfc9068, authz-access-token-iss-claim, authz-access-token-aud-claim, authz-access-token-sub-claim, authz-access-token-client-id-claim, authz-access-token-exp-short-lived, authz-access-token-iat-claim, authz-access-token-jti-claim

passed MUST core/authorization_server#authz-token-exchange-invalid-resource 16 ms

Token exchange for an unknown storage is refused with an OAuth error

verifies: authz-token-exchange-resource-param, authz-token-error-rfc6749

passed MUST core/authorization_server#authz-token-exchange-missing-resource 4 ms

Token exchange without a resource parameter is refused with invalid_request

verifies: authz-token-exchange-resource-param, authz-token-error-rfc6749

passed MUST core/authorization_server#authz-token-exchange-missing-subject-token 13 ms

Token exchange without a subject token is refused with invalid_request

verifies: authz-token-exchange-subject-token-param, authz-token-error-rfc6749

passed MUST core/authorization_server#authz-issued-token-accepted-by-storage 16 ms

The storage accepts an access token its authorization server issued

verifies: authz-token-validation-checklist, authz-jwt-signature-jwks-rotation

passed MUST core/access_grants#access-grant-endpoint-is-container 14 ms

The access grant endpoint is an LWS container

verifies: access-endpoints-are-lws-containers, access-services-advertised

passed MUST core/access_grants#access-grant-create 25 ms

A storage controller creates an access grant with POST and reads it back

verifies: access-post-location-header, access-endpoints-jsonld-payloads, access-type-values, access-storage-uri

passed SHOULD core/access_grants#access-grant-revoke 29 ms

Deleting an access grant withdraws the access it gave

verifies: access-endpoints-get-post-delete

passed MUST core/access_grants#getContainer-public-read 33 ms

A container granted to the public can be read without credentials

verifies: policy-assignee-uri-foaf-agent

passed MUST core/access_grants#readDataResource-public-read 35 ms

A data resource granted to the public can be read without credentials

verifies: policy-assignee-uri-foaf-agent

passed MUST core/access_grants#access-grant-authenticated-agent 40 ms

A read grant to one agent lets that agent read, and no more

verifies: policy-action-values, authz-policy-denial-rejected

passed MAY core/access_grants#access-grant-extra-properties-accepted 34 ms

A grant with an extra property, and without the optional inbox and constraint, is accepted and takes effect

verifies: access-extra-properties-allowed, access-inbox-optional, policy-constraint-optional

passed SHOULD core/access_grants#access-grant-inbox-notified 2,055 ms

A grant with an inbox is announced there

verifies: access-inbox-notifications, access-notification-events, access-notification-data-model, access-notification-delivery

passed MUST core/access_grants#access-request-create 20 ms

An agent submits an access request with POST

verifies: access-post-location-header, access-type-values

passed MUST core/access_grants#access-grant-document-shape 33 ms

An access grant reads back in the access data model, with every required property

verifies: access-jsonld-context-lws-v1, access-type-required, access-storage-required, access-access-required, access-access-collection, policy-type-required, policy-type-access-policy, policy-action-required, policy-assignee-required, policy-target-object

passed MUST core/access_grants#access-grant-incomplete-refused 50 ms

An access grant missing a required property, or with a malformed one, is refused and grants nothing

verifies: access-type-required, access-storage-required, access-access-required, access-access-collection, access-inbox-uri, policy-type-required, policy-type-access-policy, policy-action-required, policy-assignee-required, policy-target-object

passed MUST core/access_grants#access-grant-constraints-all-satisfied 45 ms

A grant's constraints must all be satisfied before it permits access

verifies: policy-constraints-all-satisfied, policy-constraints-conjunction-semantics, policy-constraint-left-operands, policy-constraint-objects

passed MUST core/access_grants#access-grant-left-operands-accepted 57 ms

A server advertising the Access Profile accepts a grant constrained by each leftOperand it must support

verifies: policy-constraint-left-operands, policy-constraint-objects

passed MUST core/access_grants#access-grant-constraint-format 40 ms

A format constraint lets a grant reach only resources of the listed media types

verifies: policy-constraint-left-operands

passed MUST core/access_grants#access-grant-constraint-type 40 ms

A type constraint lets a grant reach only resources of the given type

verifies: policy-constraint-left-operands

passed MUST core/access_grants#access-grant-constraint-client 39 ms

A client constraint withholds a grant from every other client application

verifies: policy-constraint-left-operands

passed MAY core/access_grants#container-listing-filtered-metadata 49 ms

A listing filtered by authorization still gives each member it shows its core metadata

verifies: read-container-listing-authz-filtered

passed MUST core/notifications#notification-service-advertised 15 ms

A storage that supports notifications advertises a well-formed NotificationService

verifies: notifications-advertise-notificationservice, notificationservice-endpoint-and-subscription-types

passed MUST core/notifications#subscription-create 5 ms

An authenticated lws+json POST to the NotificationService creates a subscription

verifies: subscription-create-post-lws-json, subscription-request-required-fields, subscription-request-type, subscription-request-topic, subscription-request-additional-fields, subscription-response-lws-json, subscription-response-type, subscription-response-subscription-url, notification-suite-subscription-type-identifier

passed MUST core/notifications#subscription-missing-type-refused 13 ms

A subscription request without a type is refused

verifies: subscription-request-required-fields, subscription-request-type

passed MUST core/notifications#subscription-unadvertised-type-refused 14 ms

A subscription request whose type the NotificationService does not advertise is refused

verifies: subscription-request-type

passed MUST core/notifications#subscription-missing-topic-refused 13 ms

A subscription request without a topic is refused

verifies: subscription-request-required-fields, subscription-request-topic

passed MUST core/notifications#subscription-unreadable-topic-refused 39 ms

A subscription naming any resource the subscriber cannot read is refused

verifies: subscription-authorization-on-create, security-notification-access-control

passed MUST core/notifications#subscription-after-revocation-refused 38 ms

Once a grant is revoked, the agent it named can no longer subscribe to the resource

verifies: subscription-authorization-on-create, security-notification-access-control

passed MUST core/notifications#notification-delivered-create 2,099 ms

A Create in a subscribed container is delivered as a well-formed Notification

verifies: notification-envelope-type, notification-envelope-storage, notification-envelope-activity, notification-activity-as2-conformance, notification-activity-id, notification-activity-type, notification-activity-object, notification-activity-object-id, notification-activity-object-type, notification-activity-published, notification-activity-types-supported

passed MUST core/notifications#notification-delivered-update 2,022 ms

An Update to a subscribed data resource is delivered

verifies: notification-activity-types-supported, notification-activity-type, notification-activity-object-id

passed MUST core/notifications#notification-delivered-delete 2,100 ms

A Delete in a subscribed container is delivered

verifies: notification-activity-types-supported, notification-activity-type, notification-activity-object-id

inapplicable MUST core/notifications#notification-not-delivered-for-unreadable-resource 40 ms

A subscriber hears nothing about a resource inside its topic that it cannot read

verifies: subscription-authorization-on-delivery, security-notification-access-control, privacy-notification-authorized-resources-only

core/notifications#notification-not-delivered-for-unreadable-resource - inapplicable [MUST] (40 ms)
  inapplicable: precondition 'bob cannot read it (otherwise access to the container reaches its members, and this test does not apply)' does not hold: status code expected 403 or 404, got 200
  step 'bob cannot read it (otherwise access to the container reaches its members, and this test does not apply)':
    FAILED status code
      expected: 403 or 404
      actual:   200
    exchange: GET http://127.0.0.1:41427/lws/harness/touchstone-run-33738dc0/notification-not-delivered-for-unreadable-resource/box/resource-mvi513or -> 200
    response body: not for bob

passed MUST core/notifications#notification-stops-after-revocation 4,020 ms

Once access to a resource is revoked, its notifications stop

verifies: subscription-authorization-revoked, subscription-authorization-on-delivery, security-notification-access-control

passed SHOULD core/notifications#notification-actor-omitted 2,097 ms

Delivered activities omit the actor by default

verifies: privacy-notification-actor-omitted, notification-activity-optional-properties

passed MUST core/notifications#notification-delivered-in-subcontainer 2,018 ms

A subscription to a container reaches a resource created in a subcontainer

verifies: notification-activity-types-supported, notification-activity-object-id

passed MUST core/notifications#notification-scope-data-resource-only 2,093 ms

A subscription to a data resource hears nothing about its siblings

verifies: notification-activity-types-supported, notification-activity-object-id

passed MUST core/pagination#pagination-first-page 5 ms

The first page of a container split into pages has rel="first" and no rel="prev"

verifies: pagination-link-first, pagination-link-prev, pagination-200-totalitems-all-pages, pagination-first-page-flow

passed MUST core/pagination#pagination-next-page 40 ms

Following rel="next" yields a further page of the same container, without the first page's members

verifies: pagination-link-first, pagination-200-totalitems-all-pages

inapplicable MUST core/pagination#pagination-single-page 30 ms

A paginated listing that holds every member on one page has neither rel="next" nor rel="prev"

verifies: pagination-link-next, pagination-link-prev, pagination-link-first

core/pagination#pagination-single-page - inapplicable [MUST] (30 ms)
  inapplicable: precondition 'the listing is paginated and holds all five members on its page (otherwise this test does not apply)' does not hold: json /items/4 selects a value expected a value at /items/4, got nothing
  step 'the listing is paginated and holds all five members on its page (otherwise this test does not apply)':
    FAILED json /items/4 selects a value
      expected: a value at /items/4
      actual:   nothing
    exchange: GET http://127.0.0.1:41427/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/ -> 200
    response body: {"@context":"https://www.w3.org/ns/lws/v1","id":"/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/","type":"Container","totalItems":5,"items":[{"type":"DataResource","id":"/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/resource-mvi513or","format":"text/plain","size":8,"modified":"2026-10-21T13:18:23.212Z"},{"type":"DataResource","id":"/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/resource-mvi513ov","format":"text/plain","size":8,"modified":"2026-10-21T13:18:23.216Z"},{"type":"DataResource","id":"/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/resource-mvi513oz","format":"text/plain","size":8,"modified":"2026-10-21T13:18:23.219Z"},{"type":"DataResource","id":"/lws/harness/touchstone-run-33738dc0/pagination-single-page/paged/resource-mvi513p0","format":"text/plain","size":8,"modified":"2026-10-21T13:18:23.221Z"}]}

passed MUST core/pagination#pagination-last-page 38 ms

The last page has rel="first" and no rel="next"

verifies: pagination-link-last, pagination-link-next, pagination-link-first

passed SHOULD core/pagination#pagination-totalitems-all-pages 33 ms

totalItems counts the whole container on every page

verifies: pagination-200-totalitems-all-pages

passed MUST auth/oidc/manifest#authn-oidc-valid-id-token 140 ms

A valid ID Token is exchanged for an access token naming its subject

verifies: id-token-token-type-uri, id-token-sub-claim, id-token-iss-claim, id-token-azp-claim, id-token-aud-claim, validation-dereference-subject-cid, validation-locate-issuer-service-and-verify

passed MUST auth/oidc/manifest#authn-oidc-expired-id-token 10 ms

An expired ID Token is refused

verifies: validation-locate-issuer-service-and-verify

passed MUST auth/oidc/manifest#authn-oidc-alg-none 5 ms

An unsigned (alg none) ID Token is refused

verifies: id-token-alg-not-none, authn-credential-signed

passed MUST auth/oidc/manifest#authn-oidc-bad-signature 93 ms

An ID Token with a corrupted signature is refused

verifies: validation-locate-issuer-service-and-verify, authn-credential-signed

passed MUST auth/oidc/manifest#authn-oidc-untrusted-issuer 44 ms

An ID Token from a provider the subject never named is refused

verifies: validation-dereference-subject-cid, validation-locate-issuer-service-and-verify

passed MUST auth/oidc/manifest#authn-oidc-missing-azp 4 ms

An ID Token without azp is refused

verifies: id-token-azp-claim, authn-client-claim

passed MUST auth/cid/manifest#authn-cid-valid-credential 8 ms

A valid self-issued credential is exchanged for an access token naming its subject

verifies: token-type-jwt, sub-claim, iss-claim, client-id-claim, sub-iss-client-same-uri, aud-includes-as, exp-claim, iat-claim, validation-dereference-sub-cid, validation-kid-verification-method, validation-all-claims, validation-exp-in-future

passed MUST auth/cid/manifest#authn-cid-unknown-kid 7 ms

A credential whose kid names no verification method is refused

verifies: validation-kid-verification-method

passed MUST auth/cid/manifest#authn-cid-bad-signature 44 ms

A credential with a corrupted signature is refused

verifies: validation-kid-verification-method, authn-credential-signed

passed MUST auth/cid/manifest#authn-cid-expired 5 ms

An expired credential is refused

verifies: validation-exp-in-future

passed MUST auth/cid/manifest#authn-cid-alg-none 3 ms

An unsigned (alg none) credential is refused

verifies: alg-not-none, validation-reject-alg-none, authn-credential-signed

passed MUST auth/cid/manifest#authn-cid-claims-mismatch 4 ms

A credential whose client_id differs from sub and iss is refused

verifies: sub-iss-client-same-uri, validation-all-claims

passed MUST auth/cid/manifest#authn-cid-document-id-mismatch 45 ms

A credential whose subject dereferences to a document with another id is refused

verifies: validation-dereference-sub-cid

passed MUST auth/cid/manifest#authn-cid-key-not-for-authentication 44 ms

A credential signed with a key the document does not list for authentication is refused

verifies: validation-kid-verification-method

passed MUST auth/cid/manifest#authn-cid-key-revoked 4 ms

A credential signed with a revoked verification method is refused

verifies: validation-kid-verification-method

passed MUST auth/cid/manifest#authn-cid-foreign-controller 45 ms

A credential signed with a verification method another identifier controls is refused

verifies: validation-kid-verification-method

passed MUST auth/cid/manifest#authn-cid-referenced-method 46 ms

A credential whose authentication method is referenced by id, not embedded, is accepted

verifies: validation-kid-verification-method, validation-dereference-sub-cid

passed MUST auth/cid/manifest#authn-cid-didkey-valid-credential 5 ms

A valid did:key credential is exchanged for an access token naming its subject

verifies: token-type-jwt, sub-claim, iss-claim, client-id-claim, sub-iss-client-same-uri, aud-includes-as, exp-claim, iat-claim, validation-dereference-sub-cid, validation-kid-verification-method, validation-all-claims, validation-exp-in-future

passed MUST auth/cid/manifest#authn-cid-didkey-invalid-signature 2 ms

A did:key credential with a corrupted signature is refused

verifies: validation-kid-verification-method, authn-credential-signed

passed MUST auth/cid/manifest#authn-cid-didkey-alg-none 4 ms

An unsigned (alg none) did:key credential is refused

verifies: alg-not-none, validation-all-claims, authn-credential-signed

passed MUST auth/cid/manifest#authn-cid-didkey-expired 2 ms

An expired did:key credential is refused

verifies: validation-exp-in-future

passed MUST auth/cid/manifest#authn-cid-didkey-claims-mismatch 2 ms

A did:key credential whose client_id differs from sub and iss is refused

verifies: sub-iss-client-same-uri, validation-all-claims

passed MUST auth/cid/manifest#authn-cid-didkey-audience-excludes-as 3 ms

A did:key credential not addressed to this authorization server is refused

verifies: aud-includes-as, validation-all-claims, authn-audience-restriction-recommended

passed MUST auth/cid/manifest#authn-cid-didkey-missing-exp 3 ms

A did:key credential without exp is refused

verifies: exp-claim, validation-all-claims

passed MUST auth/cid/manifest#authn-cid-didkey-missing-iat 3 ms

A did:key credential without iat is refused

verifies: iat-claim, validation-all-claims

passed MUST auth/cid/manifest#authn-cid-didkey-missing-subject 2 ms

A did:key credential without a sub claim is refused

verifies: authn-subject-claim-uri, authn-credential-tamper-evident-claims, sub-iss-client-same-uri

passed MUST auth/cid/manifest#authn-cid-didkey-missing-issuer 3 ms

A did:key credential without an iss claim is refused

verifies: authn-issuer-claim-uri, authn-credential-tamper-evident-claims, sub-iss-client-same-uri

passed MUST auth/cid/manifest#authn-cid-didkey-missing-client-id 3 ms

A did:key credential without a client_id claim is refused

verifies: authn-client-claim, authn-credential-tamper-evident-claims, sub-iss-client-same-uri

inapplicable MUST auth/saml/manifest#authn-saml-valid-assertion 0 ms

A valid SAML assertion is exchanged for an access token naming its subject

verifies: token-type-saml2, nameid-subject, issuer-assertion, recipient-client-id, signed-and-required-assertions, audience-restriction, validation-signature

auth/saml/manifest#authn-saml-valid-assertion - inapplicable [MUST]
  inapplicable: the target does not declare SamlTrust

inapplicable MUST auth/saml/manifest#authn-saml-invalid-signature 0 ms

A SAML assertion altered after signing is refused

verifies: validation-signature, authn-credential-signed

auth/saml/manifest#authn-saml-invalid-signature - inapplicable [MUST]
  inapplicable: the target does not declare SamlTrust

inapplicable MUST auth/saml/manifest#authn-saml-unsigned 0 ms

An unsigned SAML assertion is refused

verifies: signed-and-required-assertions, authn-credential-signed

auth/saml/manifest#authn-saml-unsigned - inapplicable [MUST]
  inapplicable: the target does not declare SamlTrust

passed MUST notifications/webhook/manifest#webhook-subscription-response 4 ms

A webhook subscription is answered with type WebhookSubscription and a subscription URL

verifies: subscription-type-and-fields, subscription-inbox-required, response-type-webhook, subscription-type-identifier

passed MUST notifications/webhook/manifest#webhook-subscription-expires-supported 4 ms

A webhook subscription request with an expires datetime is accepted

verifies: subscription-type-and-fields, subscription-expires-optional, response-expires-optional

passed MUST notifications/webhook/manifest#webhook-subscription-listed 10 ms

The NotificationService endpoint lists the subscriber's webhook subscriptions as an LWS container

verifies: subscription-listing-container

passed MUST notifications/webhook/manifest#webhook-subscription-get-delete 6 ms

A webhook subscription supports GET for its state and DELETE to cancel it

verifies: subscription-get-delete, subscription-listing-container

passed MUST notifications/webhook/manifest#webhook-delivery-lws-json 2,090 ms

A delivery is a POST to the inbox with an application/lws+json body

verifies: delivery-lws-json

passed SHOULD notifications/webhook/manifest#webhook-delivery-signed 2,088 ms

Deliveries are signed with HTTP Message Signatures

verifies: delivery-signed

passed MUST notifications/webhook/manifest#webhook-signature-components 2,130 ms

A signed delivery covers the required components and names created and keyid

verifies: signature-covered-components, signature-input-created-keyid

passed MUST notifications/webhook/manifest#webhook-signing-key-published 2,133 ms

The keyid of a signed delivery resolves to a published key in the storage description

verifies: signing-key-published, signature-input-created-keyid, keyid-url-with-fragment, storage-description-id-matches

passed MUST notifications/webhook/manifest#webhook-signature-verifies 2,131 ms

A signed delivery verifies with the published key, and its Content-Digest matches the body

verifies: signing-key-published, signature-covered-components, inbox-verifies-signature, receiver-verification-steps

passed MAY notifications/webhook/manifest#webhook-delivery-retried 3,047 ms

A delivery the inbox answers with 503 is tried again

verifies: delivery-retry-optional

passed MAY notifications/webhook/manifest#webhook-subscription-deactivated 51 ms

A subscription whose inbox keeps refusing deliveries is deactivated

verifies: delivery-deactivation-optional

passed MUST index/manifest#index-services-advertised 2 ms

Each advertised Type Index or Type Search Service has a serviceEndpoint

verifies: services-optional, service-advertised, service-endpoint

passed MUST index/manifest#type-index-lists-readable-types 7 ms

The type index lists a type borne by a resource the client may read

verifies: authorization-enforced, reflect-change-bounded

passed MUST index/manifest#type-index-omits-unreadable-type 6 ms

The type index omits a type borne only by resources the client may not read

verifies: unauthorized-omitted, no-existence-disclosure, authorization-enforced

passed MUST index/manifest#type-index-not-shared 3 ms

A type index response is marked against reuse across clients

verifies: responses-private, no-shared-cache

passed MUST index/manifest#type-search-by-type 2 ms

A search on one type returns a ContainerPage with the resource that bears it

verifies: baseline-format-supported, type-key-supported, search-default-containerpage, result-item-id-type, type-filter, reflect-change-bounded

passed MUST index/manifest#type-search-and-or 4 ms

Type groups are ANDed and the IRIs inside a group ORed

verifies: type-filter, type-key-supported

passed MUST index/manifest#type-search-native-classes 2 ms

lws:DataResource and lws:Container filter on what the resource itself is

verifies: type-filter, type-key-supported, types-from-link-headers

passed MUST index/manifest#type-search-no-match 2 ms

A type that matches nothing yields an empty result, not an error

verifies: no-match-not-error, search-default-containerpage

passed MUST index/manifest#type-search-duplicate-groups 3 ms

Duplicate groups in a filter are ignored

verifies: duplicate-groups-ignored

passed MUST index/manifest#type-search-at-members-ignored 3 ms

Filter members whose names begin with @ are ignored

verifies: at-members-ignored

passed MUST index/manifest#type-search-empty-key-absent 2 ms

A filter key whose whole value is an empty array is no constraint

verifies: type-filter

passed MUST index/manifest#type-search-empty-group-rejected 2 ms

An empty group is rejected with 400

verifies: empty-group-rejected, malformed-filter-400

passed MUST index/manifest#type-search-type-not-array-rejected 1 ms

A type that is not an array is rejected with 400

verifies: malformed-filter-400

passed MUST index/manifest#type-search-bad-element-rejected 2 ms

A type element that is not a string or array of strings is rejected with 400

verifies: malformed-filter-400, grammar-not-extended

passed MUST index/manifest#type-search-malformed-json-rejected 1 ms

A body that is not well-formed JSON is rejected with 400

verifies: malformed-filter-400

passed MUST index/manifest#type-search-relative-iri-rejected 2 ms

A type or relation value that is not an absolute IRI is rejected with 400

verifies: invalid-iri-400

passed MUST index/manifest#type-search-missing-content-type-rejected 1 ms

A search without a Content-Type is rejected with 400

verifies: missing-content-type-400, query-content-type-required

passed MUST index/manifest#type-search-unsupported-format-rejected 1 ms

A search in an unsupported query format is rejected with 415

verifies: unsupported-format-415

passed SHOULD index/manifest#type-search-unsupported-format-accept-query 1 ms

A 415 from the search lists the accepted formats in Accept-Query

verifies: unsupported-format-accept-query

passed SHOULD index/manifest#type-search-accept-query-advertised 1 ms

OPTIONS on the search endpoint advertises its query formats in Accept-Query

verifies: accept-query-advertised, accept-query-no-disclosure

passed MUST index/manifest#type-search-not-acceptable 2 ms

A search whose Accept excludes every format the server can produce is rejected with 406

verifies: not-acceptable-406, search-default-containerpage

passed MUST index/manifest#type-search-unindexed-relation 3 ms

An unindexed relation and an unmatched relation target both yield an empty result

verifies: unindexed-relation-indistinguishable, relations-may-be-indexed, no-match-not-error

passed MUST index/manifest#type-search-structural-relation-not-indexed 2 ms

A structural relation such as up is not indexed

verifies: structural-relations-not-indexed, unindexed-relation-indistinguishable

passed MUST index/manifest#type-search-authorization-filtered 4 ms

A search omits resources the client may not read, and counts only those it may

verifies: unauthorized-omitted, no-existence-disclosure, authorization-enforced, counts-filtered, derived-index-filtered

passed MUST index/manifest#type-search-revoked-not-shown 4 ms

Once a grant is revoked, the search stops returning what it gave access to

verifies: revoked-not-shown, current-authorization, consistency-not-for-authorization, derived-index-filtered

passed MUST index/manifest#type-search-not-shared 1 ms

A search response is marked against reuse across clients

verifies: responses-private, no-shared-cache

passed MAY index/manifest#type-search-type-from-content 1 ms

A type declared only in the resource's Turtle is searchable

verifies: types-from-content

passed MUST index/manifest#type-search-content-types-identical 9 ms

A type taken from content is filtered by authorization and listed in the type index like one from a Link header

verifies: content-types-identical

inapplicable SHOULD index/manifest#type-search-reflects-update 7 ms

After an update changes a resource's types, the search follows

verifies: reflect-change-bounded, types-from-link-headers

index/manifest#type-search-reflects-update - inapplicable [SHOULD] (7 ms)
  inapplicable: precondition 'replace it with a resource of type Beta, its Link headers replacing its linkset (otherwise the server does no combined updates, and this test does not apply)' does not hold: header Preference-Applied matches expected matches /(?i)(^|[,\s])set-linkset\s*($|[,;=])/, got absent
  step 'replace it with a resource of type Beta, its Link headers replacing its linkset (otherwise the server does no combined updates, and this test does not apply)':
    FAILED header Preference-Applied matches
      expected: matches /(?i)(^|[,\s])set-linkset\s*($|[,;=])/
      actual:   absent
    exchange: PUT http://127.0.0.1:41427/lws/harness/touchstone-run-33738dc0/type-search-reflects-update/resource-mvi513we -> 204

passed SHOULD index/manifest#type-search-reflects-delete 2 ms

After a resource is deleted, the search stops returning it

verifies: reflect-change-bounded

passed MUST index/manifest#type-search-vary-accept 3 ms

A search that negotiates its response format lists Accept in Vary

verifies: vary-accept, other-response-formats

passed MAY index/manifest#type-search-safe 4 ms

A search changes nothing, and repeating it gives the same result

verifies: query-safe-idempotent

passed MUST index/manifest#type-search-next-page 6 ms

Following a search result's rel=next yields the rest of the same result set

verifies: search-default-containerpage, result-item-id-type, pagination-link-first

passed MAY index/manifest#type-search-relation-filter 4 ms

A describedby link in a resource's linkset can be searched on

verifies: relations-may-be-indexed

passed MAY index/manifest#type-search-relation-cnf 10 ms

Relation values combine like type values: groups ANDed, nested arrays ORed

verifies: relations-may-be-indexed, type-filter

passed MUST index/manifest#type-search-too-complex 3 ms

A filter beyond the server's limit is refused with 422, never narrowed

verifies: too-complex-422, no-silent-narrowing

inapplicable MUST index/manifest#type-search-content-location-protected 2 ms

A search result resource named by Content-Location does not hand alice's results to bob

verifies: content-location-protected

index/manifest#type-search-content-location-protected - inapplicable [MUST] (2 ms)
  inapplicable: precondition 'the search response names a result resource (otherwise this test does not apply)' does not hold: header Content-Location present expected present, got absent
  step 'the search response names a result resource (otherwise this test does not apply)':
    FAILED header Content-Location present
      expected: present
      actual:   absent
    exchange: QUERY http://127.0.0.1:41427/lws/-/types/search -> 200
    response body: {"@context":"https://www.w3.org/ns/lws/v1","type":"ContainerPage","totalItems":1,"items":[{"id":"/lws/harness/touchstone-run-33738dc0/type-search-content-location-protected/resource-mvi513x4","type":["DataResource","http://127.0.0.1:41427/lws/harness/touchstone-run-33738dc0/type-search-content-location-protected/#ContentLocationProtectedSecret"]}]}