diff --git a/src/core/jsonschema/CMakeLists.txt b/src/core/jsonschema/CMakeLists.txt
index 637c6acfc..de550e7ce 100644
--- a/src/core/jsonschema/CMakeLists.txt
+++ b/src/core/jsonschema/CMakeLists.txt
@@ -5,7 +5,7 @@ include(./official_resolver.cmake)
 sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME jsonschema
   FOLDER "Core/JSON Schema"
   PRIVATE_HEADERS bundle.h resolver.h
-    walker.h reference.h frame.h error.h unevaluated.h
+    walker.h frame.h error.h unevaluated.h
     keywords.h transform.h
   SOURCES jsonschema.cc default_walker.cc frame.cc
     resolver.cc walker.cc bundle.cc
diff --git a/src/core/jsonschema/bundle.cc b/src/core/jsonschema/bundle.cc
index 5052e30a2..11e4fdb20 100644
--- a/src/core/jsonschema/bundle.cc
+++ b/src/core/jsonschema/bundle.cc
@@ -53,7 +53,7 @@ auto is_official_metaschema_reference(const sourcemeta::core::Pointer &pointer,
 
 auto bundle_schema(sourcemeta::core::JSON &root, const std::string &container,
                    const sourcemeta::core::JSON &subschema,
-                   sourcemeta::core::Frame &frame,
+                   sourcemeta::core::SchemaFrame &frame,
                    const sourcemeta::core::SchemaWalker &walker,
                    const sourcemeta::core::SchemaResolver &resolver,
                    const std::optional<std::string> &default_dialect) -> void {
@@ -137,7 +137,7 @@ auto bundle(sourcemeta::core::JSON &schema, const SchemaWalker &walker,
             const std::optional<std::string> &default_dialect) -> void {
   const auto vocabularies{
       sourcemeta::core::vocabularies(schema, resolver, default_dialect)};
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   bundle_schema(schema, definitions_keyword(vocabularies), schema, frame,
                 walker, resolver, default_dialect);
 }
diff --git a/src/core/jsonschema/default_walker.cc b/src/core/jsonschema/default_walker.cc
index 749a7ce9a..93f282bdb 100644
--- a/src/core/jsonschema/default_walker.cc
+++ b/src/core/jsonschema/default_walker.cc
@@ -5,7 +5,9 @@ auto sourcemeta::core::default_schema_walker(
     -> sourcemeta::core::SchemaWalkerResult {
 #define WALK(vocabulary, _keyword, strategy, ...)                              \
   if (vocabularies.contains(vocabulary) && keyword == _keyword)                \
-    return {sourcemeta::core::KeywordType::strategy, vocabulary, {__VA_ARGS__}};
+    return {sourcemeta::core::SchemaKeywordType::strategy,                     \
+            vocabulary,                                                        \
+            {__VA_ARGS__}};
 
 #define WALK_ANY(vocabulary_1, vocabulary_2, _keyword, strategy, ...)          \
   WALK(vocabulary_1, _keyword, strategy, __VA_ARGS__)                          \
@@ -306,7 +308,8 @@ auto sourcemeta::core::default_schema_walker(
   if ((vocabularies.contains(HTTP_BASE "draft-07/schema#") ||
        vocabularies.contains(HTTP_BASE "draft-07/hyper-schema#")) &&
       keyword != "$ref") {
-    return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {"$ref"}};
+    return {
+        sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {"$ref"}};
   }
 
   // Draft6
@@ -410,7 +413,8 @@ auto sourcemeta::core::default_schema_walker(
   if ((vocabularies.contains(HTTP_BASE "draft-06/schema#") ||
        vocabularies.contains(HTTP_BASE "draft-06/hyper-schema#")) &&
       keyword != "$ref") {
-    return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {"$ref"}};
+    return {
+        sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {"$ref"}};
   }
 
   // Draft4
@@ -494,7 +498,8 @@ auto sourcemeta::core::default_schema_walker(
   if ((vocabularies.contains(HTTP_BASE "draft-04/schema#") ||
        vocabularies.contains(HTTP_BASE "draft-04/hyper-schema#")) &&
       keyword != "$ref") {
-    return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {"$ref"}};
+    return {
+        sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {"$ref"}};
   }
 
   // Draft3
@@ -538,7 +543,8 @@ auto sourcemeta::core::default_schema_walker(
   // $ref also takes precedence over any unknown keyword
   if (vocabularies.contains(HTTP_BASE "draft-03/schema#") &&
       keyword != "$ref") {
-    return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {"$ref"}};
+    return {
+        sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {"$ref"}};
   }
 
   // Draft2
@@ -662,5 +668,5 @@ auto sourcemeta::core::default_schema_walker(
 #undef WALK
 #undef WALK_ANY
 #undef WALK_MAYBE_DEPENDENT
-  return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {}};
+  return {sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {}};
 }
diff --git a/src/core/jsonschema/frame.cc b/src/core/jsonschema/frame.cc
index cffe597a0..02e566dc0 100644
--- a/src/core/jsonschema/frame.cc
+++ b/src/core/jsonschema/frame.cc
@@ -175,9 +175,9 @@ static auto fragment_string(const sourcemeta::core::URI &uri)
   return std::nullopt;
 }
 
-static auto store(sourcemeta::core::Frame::Locations &frame,
-                  const sourcemeta::core::ReferenceType type,
-                  const sourcemeta::core::Frame::LocationType entry_type,
+static auto store(sourcemeta::core::SchemaFrame::Locations &frame,
+                  const sourcemeta::core::SchemaReferenceType type,
+                  const sourcemeta::core::SchemaFrame::LocationType entry_type,
                   const std::string &uri,
                   const std::optional<std::string> &root_id,
                   const std::string &base_id,
@@ -210,8 +210,8 @@ struct InternalEntry {
 };
 
 auto internal_analyse(const sourcemeta::core::JSON &schema,
-                      sourcemeta::core::Frame::Locations &frame,
-                      sourcemeta::core::Frame::References &references,
+                      sourcemeta::core::SchemaFrame::Locations &frame,
+                      sourcemeta::core::SchemaFrame::References &references,
                       const sourcemeta::core::SchemaWalker &walker,
                       const sourcemeta::core::SchemaResolver &resolver,
                       const std::optional<std::string> &default_dialect,
@@ -242,10 +242,11 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
                                        default_id.has_value() &&
                                        root_id.value() != default_id.value()};
   if (has_explicit_different_id) {
-    store(frame, ReferenceType::Static, Frame::LocationType::Resource,
-          default_id.value(), root_id.value(), root_id.value(),
-          sourcemeta::core::empty_pointer, sourcemeta::core::empty_pointer,
-          root_dialect.value(), root_base_dialect.value());
+    store(frame, SchemaReferenceType::Static,
+          SchemaFrame::LocationType::Resource, default_id.value(),
+          root_id.value(), root_id.value(), sourcemeta::core::empty_pointer,
+          sourcemeta::core::empty_pointer, root_dialect.value(),
+          root_base_dialect.value());
     base_uris.insert({sourcemeta::core::empty_pointer, {default_id.value()}});
   }
 
@@ -302,11 +303,12 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
           const std::string new_id{maybe_relative.recompose()};
 
           if (!maybe_relative_is_absolute ||
-              !frame.contains({ReferenceType::Static, new_id})) {
+              !frame.contains({SchemaReferenceType::Static, new_id})) {
             assert(entry.common.base_dialect.has_value());
-            store(frame, ReferenceType::Static, Frame::LocationType::Resource,
-                  new_id, root_id, new_id, entry.common.pointer,
-                  sourcemeta::core::empty_pointer, entry.common.dialect.value(),
+            store(frame, SchemaReferenceType::Static,
+                  SchemaFrame::LocationType::Resource, new_id, root_id, new_id,
+                  entry.common.pointer, sourcemeta::core::empty_pointer,
+                  entry.common.dialect.value(),
                   entry.common.base_dialect.value());
           }
 
@@ -333,10 +335,11 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
       const std::string destination{metaschema.recompose()};
       assert(entry.common.value.defines("$schema"));
       references.insert_or_assign(
-          {ReferenceType::Static, entry.common.pointer.concat({"$schema"})},
-          Frame::ReferencesEntry{destination,
-                                 metaschema.recompose_without_fragment(),
-                                 fragment_string(metaschema)});
+          {SchemaReferenceType::Static,
+           entry.common.pointer.concat({"$schema"})},
+          SchemaFrame::ReferencesEntry{destination,
+                                       metaschema.recompose_without_fragment(),
+                                       fragment_string(metaschema)});
     }
 
     // Handle schema anchors
@@ -350,16 +353,18 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
         const auto relative_anchor_uri{anchor_uri.recompose()};
 
         if (type == AnchorType::Static || type == AnchorType::All) {
-          store(frame, ReferenceType::Static, Frame::LocationType::Anchor,
-                relative_anchor_uri, root_id, "", entry.common.pointer,
+          store(frame, SchemaReferenceType::Static,
+                SchemaFrame::LocationType::Anchor, relative_anchor_uri, root_id,
+                "", entry.common.pointer,
                 entry.common.pointer.resolve_from(bases.second),
                 entry.common.dialect.value(),
                 entry.common.base_dialect.value());
         }
 
         if (type == AnchorType::Dynamic || type == AnchorType::All) {
-          store(frame, ReferenceType::Dynamic, Frame::LocationType::Anchor,
-                relative_anchor_uri, root_id, "", entry.common.pointer,
+          store(frame, SchemaReferenceType::Dynamic,
+                SchemaFrame::LocationType::Anchor, relative_anchor_uri, root_id,
+                "", entry.common.pointer,
                 entry.common.pointer.resolve_from(bases.second),
                 entry.common.dialect.value(),
                 entry.common.base_dialect.value());
@@ -367,8 +372,9 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
           // Register a dynamic anchor as a static anchor if possible too
           if (entry.common.vocabularies.contains(
                   "https://json-schema.org/draft/2020-12/vocab/core")) {
-            store(frame, ReferenceType::Static, Frame::LocationType::Anchor,
-                  relative_anchor_uri, root_id, "", entry.common.pointer,
+            store(frame, SchemaReferenceType::Static,
+                  SchemaFrame::LocationType::Anchor, relative_anchor_uri,
+                  root_id, "", entry.common.pointer,
                   entry.common.pointer.resolve_from(bases.second),
                   entry.common.dialect.value(),
                   entry.common.base_dialect.value(), true);
@@ -390,23 +396,23 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
                                     .recompose()};
 
           if (!is_first &&
-              frame.contains({ReferenceType::Static, anchor_uri})) {
+              frame.contains({SchemaReferenceType::Static, anchor_uri})) {
             continue;
           }
 
           if (type == AnchorType::Static || type == AnchorType::All) {
-            store(frame, sourcemeta::core::ReferenceType::Static,
-                  Frame::LocationType::Anchor, anchor_uri, root_id, base_string,
-                  entry.common.pointer,
+            store(frame, sourcemeta::core::SchemaReferenceType::Static,
+                  SchemaFrame::LocationType::Anchor, anchor_uri, root_id,
+                  base_string, entry.common.pointer,
                   entry.common.pointer.resolve_from(bases.second),
                   entry.common.dialect.value(),
                   entry.common.base_dialect.value());
           }
 
           if (type == AnchorType::Dynamic || type == AnchorType::All) {
-            store(frame, sourcemeta::core::ReferenceType::Dynamic,
-                  Frame::LocationType::Anchor, anchor_uri, root_id, base_string,
-                  entry.common.pointer,
+            store(frame, sourcemeta::core::SchemaReferenceType::Dynamic,
+                  SchemaFrame::LocationType::Anchor, anchor_uri, root_id,
+                  base_string, entry.common.pointer,
                   entry.common.pointer.resolve_from(bases.second),
                   entry.common.dialect.value(),
                   entry.common.base_dialect.value());
@@ -414,8 +420,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
             // Register a dynamic anchor as a static anchor if possible too
             if (entry.common.vocabularies.contains(
                     "https://json-schema.org/draft/2020-12/vocab/core")) {
-              store(frame, sourcemeta::core::ReferenceType::Static,
-                    Frame::LocationType::Anchor, anchor_uri, root_id,
+              store(frame, sourcemeta::core::SchemaReferenceType::Static,
+                    SchemaFrame::LocationType::Anchor, anchor_uri, root_id,
                     base_string, entry.common.pointer,
                     entry.common.pointer.resolve_from(bases.second),
                     entry.common.dialect.value(),
@@ -453,25 +459,27 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
       relative_pointer_uri.canonicalize();
       const auto result{relative_pointer_uri.recompose()};
 
-      if (!frame.contains({ReferenceType::Static, result})) {
+      if (!frame.contains({SchemaReferenceType::Static, result})) {
         const auto nearest_bases{
             find_nearest_bases(base_uris, pointer, base.first)};
         assert(!nearest_bases.first.empty());
         const auto &current_base{nearest_bases.first.front()};
         const auto maybe_base_entry{
-            frame.find({ReferenceType::Static, current_base})};
+            frame.find({SchemaReferenceType::Static, current_base})};
         const auto current_base_dialect{
             maybe_base_entry == frame.cend()
                 ? root_base_dialect.value()
                 : maybe_base_entry->second.base_dialect};
         if (subschemas.contains(pointer)) {
-          store(frame, ReferenceType::Static, Frame::LocationType::Subschema,
-                result, root_id, current_base, pointer,
+          store(frame, SchemaReferenceType::Static,
+                SchemaFrame::LocationType::Subschema, result, root_id,
+                current_base, pointer,
                 pointer.resolve_from(nearest_bases.second),
                 dialects.first.front(), current_base_dialect);
         } else {
-          store(frame, ReferenceType::Static, Frame::LocationType::Pointer,
-                result, root_id, current_base, pointer,
+          store(frame, SchemaReferenceType::Static,
+                SchemaFrame::LocationType::Pointer, result, root_id,
+                current_base, pointer,
                 pointer.resolve_from(nearest_bases.second),
                 dialects.first.front(), current_base_dialect);
         }
@@ -493,10 +501,11 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
 
         ref.canonicalize();
         references.insert_or_assign(
-            {ReferenceType::Static, entry.common.pointer.concat({"$ref"})},
-            Frame::ReferencesEntry{ref.recompose(),
-                                   ref.recompose_without_fragment(),
-                                   fragment_string(ref)});
+            {SchemaReferenceType::Static,
+             entry.common.pointer.concat({"$ref"})},
+            SchemaFrame::ReferencesEntry{ref.recompose(),
+                                         ref.recompose_without_fragment(),
+                                         fragment_string(ref)});
       }
 
       if (entry.common.vocabularies.contains(
@@ -518,16 +527,16 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
         auto anchor_uri_string{
             nearest_bases.first.empty() ? "" : nearest_bases.first.front()};
         const auto recursive_anchor{
-            frame.find({ReferenceType::Dynamic, anchor_uri_string})};
+            frame.find({SchemaReferenceType::Dynamic, anchor_uri_string})};
         const auto reference_type{recursive_anchor == frame.end()
-                                      ? ReferenceType::Static
-                                      : ReferenceType::Dynamic};
+                                      ? SchemaReferenceType::Static
+                                      : SchemaReferenceType::Dynamic};
         const sourcemeta::core::URI anchor_uri{std::move(anchor_uri_string)};
         references.insert_or_assign(
             {reference_type, entry.common.pointer.concat({"$recursiveRef"})},
-            Frame::ReferencesEntry{anchor_uri.recompose(),
-                                   anchor_uri.recompose_without_fragment(),
-                                   fragment_string(anchor_uri)});
+            SchemaFrame::ReferencesEntry{
+                anchor_uri.recompose(), anchor_uri.recompose_without_fragment(),
+                fragment_string(anchor_uri)});
       }
 
       if (entry.common.vocabularies.contains(
@@ -549,19 +558,20 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
 
         const auto has_fragment{ref.fragment().has_value()};
         const auto maybe_static_frame{
-            frame.find({ReferenceType::Static, ref_string})};
+            frame.find({SchemaReferenceType::Static, ref_string})};
         const auto maybe_dynamic_frame{
-            frame.find({ReferenceType::Dynamic, ref_string})};
+            frame.find({SchemaReferenceType::Dynamic, ref_string})};
         const auto behaves_as_static{!has_fragment ||
                                      (has_fragment &&
                                       maybe_static_frame != frame.end() &&
                                       maybe_dynamic_frame == frame.end())};
         references.insert_or_assign(
-            {behaves_as_static ? ReferenceType::Static : ReferenceType::Dynamic,
+            {behaves_as_static ? SchemaReferenceType::Static
+                               : SchemaReferenceType::Dynamic,
              entry.common.pointer.concat({"$dynamicRef"})},
-            Frame::ReferencesEntry{std::move(ref_string),
-                                   ref.recompose_without_fragment(),
-                                   fragment_string(ref)});
+            SchemaFrame::ReferencesEntry{std::move(ref_string),
+                                         ref.recompose_without_fragment(),
+                                         fragment_string(ref)});
       }
     }
   }
@@ -574,18 +584,18 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
         // TODO: This check might need to be more elaborate given
         // https://github.com/sourcemeta/core/issues/1390
         return reference.first.second.back().to_property() == "$schema" ||
-               frame.contains(
-                   {ReferenceType::Static, reference.second.destination}) ||
-               frame.contains(
-                   {ReferenceType::Dynamic, reference.second.destination});
+               frame.contains({SchemaReferenceType::Static,
+                               reference.second.destination}) ||
+               frame.contains({SchemaReferenceType::Dynamic,
+                               reference.second.destination});
       })};
 
   if (standalone) {
     // Find all dynamic anchors
     std::map<std::string, std::vector<std::string>> dynamic_anchors;
     for (const auto &entry : frame) {
-      if (entry.first.first != ReferenceType::Dynamic ||
-          entry.second.type != Frame::LocationType::Anchor) {
+      if (entry.first.first != SchemaReferenceType::Dynamic ||
+          entry.second.type != SchemaFrame::LocationType::Anchor) {
         continue;
       }
 
@@ -601,10 +611,10 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
     // If there is a dynamic reference that only has one possible
     // dynamic anchor destination, then that dynamic reference
     // is a static reference in disguise
-    std::vector<Frame::References::key_type> to_delete;
-    std::vector<Frame::References::value_type> to_insert;
+    std::vector<SchemaFrame::References::key_type> to_delete;
+    std::vector<SchemaFrame::References::value_type> to_insert;
     for (const auto &reference : references) {
-      if (reference.first.first != ReferenceType::Dynamic ||
+      if (reference.first.first != SchemaReferenceType::Dynamic ||
           !reference.second.fragment.has_value()) {
         continue;
       }
@@ -620,9 +630,9 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
       to_delete.push_back(reference.first);
       const URI new_destination{match->second.front()};
       to_insert.emplace_back(
-          Frame::References::key_type{ReferenceType::Static,
-                                      reference.first.second},
-          Frame::References::mapped_type{
+          SchemaFrame::References::key_type{SchemaReferenceType::Static,
+                                            reference.first.second},
+          SchemaFrame::References::mapped_type{
               match->second.front(),
               new_destination.recompose_without_fragment(),
               fragment_string(new_destination)});
@@ -664,61 +674,64 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
 
 namespace sourcemeta::core {
 
-auto Frame::analyse(const JSON &schema, const SchemaWalker &walker,
-                    const SchemaResolver &resolver,
-                    const std::optional<std::string> &default_dialect,
-                    const std::optional<std::string> &default_id) -> void {
+auto SchemaFrame::analyse(const JSON &schema, const SchemaWalker &walker,
+                          const SchemaResolver &resolver,
+                          const std::optional<std::string> &default_dialect,
+                          const std::optional<std::string> &default_id)
+    -> void {
   internal_analyse(schema, this->locations_, this->references_, walker,
                    resolver, default_dialect, default_id);
 }
 
-auto Frame::locations() const noexcept -> const Locations & {
+auto SchemaFrame::locations() const noexcept -> const Locations & {
   return this->locations_;
 }
 
-auto Frame::references() const noexcept -> const References & {
+auto SchemaFrame::references() const noexcept -> const References & {
   return this->references_;
 }
 
-auto Frame::vocabularies(const LocationsEntry &location,
-                         const SchemaResolver &resolver) const
+auto SchemaFrame::vocabularies(const LocationsEntry &location,
+                               const SchemaResolver &resolver) const
     -> std::map<std::string, bool> {
   return sourcemeta::core::vocabularies(resolver, location.base_dialect,
                                         location.dialect);
 }
 
-auto Frame::uri(const LocationsEntry &location,
-                const Pointer &relative_schema_location) const -> std::string {
+auto SchemaFrame::uri(const LocationsEntry &location,
+                      const Pointer &relative_schema_location) const
+    -> std::string {
   return to_uri(location.relative_pointer.concat(relative_schema_location),
                 location.base)
       .recompose();
 }
 
-auto Frame::traverse(const LocationsEntry &location,
-                     const Pointer &relative_schema_location) const
+auto SchemaFrame::traverse(const LocationsEntry &location,
+                           const Pointer &relative_schema_location) const
     -> const LocationsEntry & {
   const auto new_uri{this->uri(location, relative_schema_location)};
   const auto static_match{
-      this->locations_.find({ReferenceType::Static, new_uri})};
+      this->locations_.find({SchemaReferenceType::Static, new_uri})};
   if (static_match != this->locations_.cend()) {
     return static_match->second;
   }
 
   const auto dynamic_match{
-      this->locations_.find({ReferenceType::Dynamic, new_uri})};
+      this->locations_.find({SchemaReferenceType::Dynamic, new_uri})};
   assert(dynamic_match != this->locations_.cend());
   return dynamic_match->second;
 }
 
-auto Frame::traverse(const std::string &uri) const
+auto SchemaFrame::traverse(const std::string &uri) const
     -> std::optional<std::reference_wrapper<const LocationsEntry>> {
-  const auto static_result{this->locations_.find({ReferenceType::Static, uri})};
+  const auto static_result{
+      this->locations_.find({SchemaReferenceType::Static, uri})};
   if (static_result != this->locations_.cend()) {
     return static_result->second;
   }
 
   const auto dynamic_result{
-      this->locations_.find({ReferenceType::Dynamic, uri})};
+      this->locations_.find({SchemaReferenceType::Dynamic, uri})};
   if (dynamic_result != this->locations_.cend()) {
     return dynamic_result->second;
   }
@@ -726,30 +739,31 @@ auto Frame::traverse(const std::string &uri) const
   return std::nullopt;
 }
 
-auto Frame::dereference(const LocationsEntry &location,
-                        const Pointer &relative_schema_location) const
-    -> std::pair<ReferenceType,
+auto SchemaFrame::dereference(const LocationsEntry &location,
+                              const Pointer &relative_schema_location) const
+    -> std::pair<SchemaReferenceType,
                  std::optional<std::reference_wrapper<const LocationsEntry>>> {
   const auto effective_location{
       location.pointer.concat({relative_schema_location})};
-  const auto maybe_reference_entry{
-      this->references_.find({ReferenceType::Static, effective_location})};
+  const auto maybe_reference_entry{this->references_.find(
+      {SchemaReferenceType::Static, effective_location})};
   if (maybe_reference_entry == this->references_.cend()) {
     // If static dereferencing failed but we know the reference
     // is dynamic, then report so, but without a location, as by
     // definition we can't know the destination until at runtime
     if (this->references_.contains(
-            {ReferenceType::Dynamic, effective_location})) {
-      return {ReferenceType::Dynamic, std::nullopt};
+            {SchemaReferenceType::Dynamic, effective_location})) {
+      return {SchemaReferenceType::Dynamic, std::nullopt};
     }
 
-    return {ReferenceType::Static, std::nullopt};
+    return {SchemaReferenceType::Static, std::nullopt};
   }
 
-  const auto destination{this->locations_.find(
-      {ReferenceType::Static, maybe_reference_entry->second.destination})};
+  const auto destination{
+      this->locations_.find({SchemaReferenceType::Static,
+                             maybe_reference_entry->second.destination})};
   assert(destination != this->locations_.cend());
-  return {ReferenceType::Static, destination->second};
+  return {SchemaReferenceType::Static, destination->second};
 }
 
 } // namespace sourcemeta::core
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema.h
index 7007e5055..3602ad666 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema.h
@@ -10,7 +10,6 @@
 #include <sourcemeta/core/jsonschema_error.h>
 #include <sourcemeta/core/jsonschema_frame.h>
 #include <sourcemeta/core/jsonschema_keywords.h>
-#include <sourcemeta/core/jsonschema_reference.h>
 #include <sourcemeta/core/jsonschema_resolver.h>
 #include <sourcemeta/core/jsonschema_transform.h>
 #include <sourcemeta/core/jsonschema_unevaluated.h>
@@ -49,7 +48,7 @@ auto is_schema(const JSON &schema) -> bool;
 
 /// @ingroup jsonschema
 /// The strategy to follow when attempting to identify a schema
-enum class IdentificationStrategy : std::uint8_t {
+enum class SchemaIdentificationStrategy : std::uint8_t {
   /// Only proceed if we can guarantee the identifier is valid
   Strict,
 
@@ -83,11 +82,11 @@ enum class IdentificationStrategy : std::uint8_t {
 /// guessing game. Often useful if you have a schema without a dialect and you
 /// want to at least try to get something.
 SOURCEMETA_CORE_JSONSCHEMA_EXPORT
-auto identify(
-    const JSON &schema, const SchemaResolver &resolver,
-    const IdentificationStrategy strategy = IdentificationStrategy::Strict,
-    const std::optional<std::string> &default_dialect = std::nullopt,
-    const std::optional<std::string> &default_id = std::nullopt)
+auto identify(const JSON &schema, const SchemaResolver &resolver,
+              const SchemaIdentificationStrategy strategy =
+                  SchemaIdentificationStrategy::Strict,
+              const std::optional<std::string> &default_dialect = std::nullopt,
+              const std::optional<std::string> &default_id = std::nullopt)
     -> std::optional<std::string>;
 
 /// @ingroup jsonschema
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h
index 51c1d35e7..6fa6db1bb 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h
@@ -6,7 +6,7 @@
 #endif
 
 #include <sourcemeta/core/jsonpointer.h>
-#include <sourcemeta/core/jsonschema_reference.h>
+#include <sourcemeta/core/jsonschema_keywords.h>
 #include <sourcemeta/core/jsonschema_resolver.h>
 #include <sourcemeta/core/jsonschema_walker.h>
 
@@ -44,59 +44,59 @@ namespace sourcemeta::core {
 ///   }
 /// })JSON");
 ///
-/// sourcemeta::core::Frame frame;
+/// sourcemeta::core::SchemaSchemaFrame frame;
 /// frame.analyse(document,
 ///   sourcemeta::core::default_schema_walker,
 ///   sourcemeta::core::official_resolver);
 ///
 /// // IDs
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/foo"}));
 ///
 /// // Anchors
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#test"}));
 ///
 /// // Root Pointers
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/$id"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/$schema"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/items"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/items/$id"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/items/type"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties/foo"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties/foo/$anchor"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties/foo/type"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties/bar"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/schema#/properties/bar/$ref"}));
 ///
 /// // Subpointers
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/foo#/$id"}));
-/// assert(frame.locations().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.locations().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   "https://www.example.com/foo#/type"}));
 ///
 /// // References
-/// assert(frame.references().contains({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.references().contains({sourcemeta::core::SchemaReferenceType::Static,
 ///   { "properties", "bar", "$ref" }}));
-/// assert(frame.references().at({sourcemeta::core::ReferenceType::Static,
+/// assert(frame.references().at({sourcemeta::core::SchemaReferenceType::Static,
 ///   { "properties", "bar", "$ref" }}).destination ==
 ///     "https://www.example.com/schema#/properties/foo");
 /// ```
-class SOURCEMETA_CORE_JSONSCHEMA_EXPORT Frame {
+class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
 public:
   /// A single entry in a JSON Schema reference map
   struct ReferencesEntry {
@@ -113,7 +113,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT Frame {
   /// have a static and a dynamic reference to the same location
   /// on the same schema object.
   using References =
-      std::map<std::pair<ReferenceType, Pointer>, ReferencesEntry>;
+      std::map<std::pair<SchemaReferenceType, Pointer>, ReferencesEntry>;
 
 #if defined(__GNUC__)
 #pragma GCC diagnostic push
@@ -150,7 +150,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT Frame {
   /// JSON Pointers within the schema, and subschemas dialects. We call it
   /// reference frame as this mapping is essential for resolving references.
   using Locations =
-      std::map<std::pair<ReferenceType, std::string>, LocationsEntry>;
+      std::map<std::pair<SchemaReferenceType, std::string>, LocationsEntry>;
 
   /// Analyse a given schema
   auto analyse(const JSON &schema, const SchemaWalker &walker,
@@ -188,7 +188,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT Frame {
   auto
   dereference(const LocationsEntry &location,
               const Pointer &relative_schema_location = empty_pointer) const
-      -> std::pair<ReferenceType,
+      -> std::pair<SchemaReferenceType,
                    std::optional<std::reference_wrapper<const LocationsEntry>>>;
 
 private:
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_keywords.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_keywords.h
index b744ead99..3f6b582fa 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_keywords.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_keywords.h
@@ -5,6 +5,10 @@
 
 namespace sourcemeta::core {
 
+/// @ingroup jsonschema
+/// The reference type
+enum class SchemaReferenceType : std::uint8_t { Static, Dynamic };
+
 #if defined(__GNUC__)
 #pragma GCC diagnostic push
 // For some strange reason, GCC on Debian 11 believes that a member of
@@ -14,7 +18,7 @@ namespace sourcemeta::core {
 #endif
 /// @ingroup jsonschema
 /// Determines the type of a JSON Schema keyword
-enum class KeywordType : std::uint8_t {
+enum class SchemaKeywordType : std::uint8_t {
   /// The JSON Schema keyword is unknown
   Unknown,
   /// The JSON Schema keyword is a non-applicator assertion
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_reference.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_reference.h
deleted file mode 100644
index c24393db3..000000000
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_reference.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef SOURCEMETA_CORE_JSONSCHEMA_REFERENCE_H_
-#define SOURCEMETA_CORE_JSONSCHEMA_REFERENCE_H_
-
-#include <cstdint> // std::uint8_t
-
-namespace sourcemeta::core {
-
-/// @ingroup jsonschema
-/// The reference type
-enum class ReferenceType : std::uint8_t { Static, Dynamic };
-
-} // namespace sourcemeta::core
-
-#endif
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_resolver.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_resolver.h
index 370c20ed0..a72708708 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_resolver.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_resolver.h
@@ -47,7 +47,7 @@ auto official_resolver(std::string_view identifier)
 /// #include <cassert>
 ///
 /// // (1) Create a map resolver that falls back to the official resolver
-/// sourcemeta::core::MapSchemaResolver
+/// sourcemeta::core::SchemaMapResolver
 ///   resolver{sourcemeta::core::official_resolver};
 ///
 /// const sourcemeta::core::JSON schema =
@@ -62,14 +62,14 @@ auto official_resolver(std::string_view identifier)
 ///
 /// assert(resolver("https://www.example.com").has_value());
 /// ```
-class SOURCEMETA_CORE_JSONSCHEMA_EXPORT MapSchemaResolver {
+class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaMapResolver {
 public:
   /// Construct an empty resolver. If you don't add schemas to it, it will
   /// always resolve to nothing
-  MapSchemaResolver();
+  SchemaMapResolver();
 
   /// Construct an empty resolver that has another schema resolver as a fallback
-  MapSchemaResolver(const SchemaResolver &resolver);
+  SchemaMapResolver(const SchemaResolver &resolver);
 
   /// Register a schema to the map resolver
   auto add(const JSON &schema,
@@ -104,7 +104,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT MapSchemaResolver {
 /// #include <cassert>
 ///
 /// // (1) Create a flat file resolver that falls back to the official resolver
-/// sourcemeta::core::FlatFileSchemaResolver
+/// sourcemeta::core::SchemaFlatFileResolver
 ///   resolver{sourcemeta::core::official_resolver};
 ///
 /// // (2) Register a schema by path
@@ -112,14 +112,14 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT MapSchemaResolver {
 ///
 /// assert(resolver("https://www.example.com").has_value());
 /// ```
-class SOURCEMETA_CORE_JSONSCHEMA_EXPORT FlatFileSchemaResolver {
+class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFlatFileResolver {
 public:
   /// Construct an empty resolver. If you don't add schemas to it, it will
   /// always resolve to nothing
-  FlatFileSchemaResolver();
+  SchemaFlatFileResolver();
 
   /// Construct an empty resolver that has another schema resolver as a fallback
-  FlatFileSchemaResolver(const SchemaResolver &resolver);
+  SchemaFlatFileResolver(const SchemaResolver &resolver);
 
   /// Determines how to access the registered file entry, letting you hook
   /// into how schemas are read to support other file formats, like YAML
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_unevaluated.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_unevaluated.h
index 7e12bd16e..2d287155a 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_unevaluated.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_unevaluated.h
@@ -19,7 +19,7 @@
 namespace sourcemeta::core {
 
 /// @ingroup jsonschema
-struct UnevaluatedEntry {
+struct SchemaUnevaluatedEntry {
   /// The absolute pointers of the static keyword dependencies
   std::set<Pointer> static_dependencies;
   /// The absolute pointers of the static keyword dependencies
@@ -31,7 +31,7 @@ struct UnevaluatedEntry {
 
 /// @ingroup jsonschema
 /// The flattened set of unevaluated cases in the schema by absolute URI
-using UnevaluatedEntries = std::map<std::string, UnevaluatedEntry>;
+using SchemaUnevaluatedEntries = std::map<std::string, SchemaUnevaluatedEntry>;
 
 // TODO: Eventually generalize this to list every cross-dependency between
 // keywords, supporting extensibility of custom vocabularies too
@@ -54,7 +54,7 @@ using UnevaluatedEntries = std::map<std::string, UnevaluatedEntry>;
 ///   "unevaluatedProperties": false
 /// })JSON");
 ///
-/// sourcemeta::core::Frame frame;
+/// sourcemeta::core::SchemaSchemaFrame frame;
 /// frame.analyse(document,
 ///   sourcemeta::core::default_schema_walker,
 ///   sourcemeta::core::official_resolver);
@@ -67,9 +67,9 @@ using UnevaluatedEntries = std::map<std::string, UnevaluatedEntry>;
 /// assert(!result.at("#/unevaluatedProperties").dynamic);
 /// assert(result.at("#/unevaluatedProperties").dependencies.empty());
 /// ```
-auto SOURCEMETA_CORE_JSONSCHEMA_EXPORT
-unevaluated(const JSON &schema, const Frame &frame, const SchemaWalker &walker,
-            const SchemaResolver &resolver) -> UnevaluatedEntries;
+auto SOURCEMETA_CORE_JSONSCHEMA_EXPORT unevaluated(
+    const JSON &schema, const SchemaFrame &frame, const SchemaWalker &walker,
+    const SchemaResolver &resolver) -> SchemaUnevaluatedEntries;
 
 } // namespace sourcemeta::core
 
diff --git a/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h b/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h
index 3bdcf7352..666eb379c 100644
--- a/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h
+++ b/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h
@@ -25,7 +25,7 @@ namespace sourcemeta::core {
 /// A structure that encapsulates the result of walker over a specific keyword
 struct SchemaWalkerResult {
   /// The walker strategy to continue traversing across the schema
-  const KeywordType type;
+  const SchemaKeywordType type;
   /// The vocabulary associated with the keyword, if any
   const std::optional<std::string> vocabulary;
   /// The keywords a given keyword depends on (if any) during the evaluation
@@ -54,7 +54,7 @@ SOURCEMETA_CORE_JSONSCHEMA_EXPORT
 inline auto schema_walker_none(std::string_view,
                                const std::map<std::string, bool> &)
     -> sourcemeta::core::SchemaWalkerResult {
-  return {KeywordType::Unknown, std::nullopt, {}};
+  return {SchemaKeywordType::Unknown, std::nullopt, {}};
 }
 
 /// @ingroup jsonschema
@@ -233,16 +233,16 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaIteratorFlat {
 ///   sourcemeta::core::vocabularies(
 ///     document, sourcemeta::core::official_resolver)};
 ///
-/// assert(sourcemeta::core::keyword_priority(
+/// assert(sourcemeta::core::schema_keyword_priority(
 ///   "prefixItems", vocabularies,
 ///   sourcemeta::core::default_schema_walker) == 0);
 ///
 /// // The "items" keyword must be evaluated after the "prefixItems" keyword
-/// assert(sourcemeta::core::keyword_priority(
+/// assert(sourcemeta::core::schema_keyword_priority(
 ///   "items", vocabularies,
 ///   sourcemeta::core::default_schema_walker) == 1);
 /// ```
-auto SOURCEMETA_CORE_JSONSCHEMA_EXPORT keyword_priority(
+auto SOURCEMETA_CORE_JSONSCHEMA_EXPORT schema_keyword_priority(
     std::string_view keyword, const std::map<std::string, bool> &vocabularies,
     const SchemaWalker &walker) -> std::uint64_t;
 
diff --git a/src/core/jsonschema/jsonschema.cc b/src/core/jsonschema/jsonschema.cc
index 37e9f49d7..34e2d5966 100644
--- a/src/core/jsonschema/jsonschema.cc
+++ b/src/core/jsonschema/jsonschema.cc
@@ -57,7 +57,7 @@ static auto id_keyword(const std::string &base_dialect) -> std::string {
 
 auto sourcemeta::core::identify(
     const sourcemeta::core::JSON &schema, const SchemaResolver &resolver,
-    const IdentificationStrategy strategy,
+    const SchemaIdentificationStrategy strategy,
     const std::optional<std::string> &default_dialect,
     const std::optional<std::string> &default_id)
     -> std::optional<std::string> {
@@ -70,7 +70,7 @@ auto sourcemeta::core::identify(
         sourcemeta::core::base_dialect(schema, resolver, default_dialect);
   } catch (const SchemaResolutionError &) {
     // Attempt to play a heuristic guessing game before giving up
-    if (strategy == IdentificationStrategy::Loose && schema.is_object()) {
+    if (strategy == SchemaIdentificationStrategy::Loose && schema.is_object()) {
       const auto keyword{id_keyword_guess(schema)};
       if (keyword.has_value()) {
         return schema.at(keyword.value()).to_string();
@@ -84,7 +84,7 @@ auto sourcemeta::core::identify(
 
   if (!maybe_base_dialect.has_value()) {
     // Attempt to play a heuristic guessing game before giving up
-    if (strategy == IdentificationStrategy::Loose && schema.is_object()) {
+    if (strategy == SchemaIdentificationStrategy::Loose && schema.is_object()) {
       const auto keyword{id_keyword_guess(schema)};
       if (keyword.has_value()) {
         return schema.at(keyword.value()).to_string();
diff --git a/src/core/jsonschema/relativize.cc b/src/core/jsonschema/relativize.cc
index da9120749..809dccaad 100644
--- a/src/core/jsonschema/relativize.cc
+++ b/src/core/jsonschema/relativize.cc
@@ -6,12 +6,12 @@ auto relativize(JSON &schema, const SchemaWalker &walker,
                 const SchemaResolver &resolver,
                 const std::optional<std::string> &default_dialect,
                 const std::optional<std::string> &default_id) -> void {
-  Frame frame;
+  SchemaFrame frame;
   frame.analyse(schema, walker, resolver, default_dialect, default_id);
 
   for (const auto &entry : frame.locations()) {
-    if (entry.second.type != Frame::LocationType::Resource &&
-        entry.second.type != Frame::LocationType::Subschema) {
+    if (entry.second.type != SchemaFrame::LocationType::Resource &&
+        entry.second.type != SchemaFrame::LocationType::Subschema) {
       continue;
     }
 
@@ -24,7 +24,7 @@ auto relativize(JSON &schema, const SchemaWalker &walker,
     const auto base{URI{entry.second.base}.canonicalize()};
     for (const auto &property : subschema.as_object()) {
       if (walker(property.first, frame.vocabularies(entry.second, resolver))
-                  .type != KeywordType::Reference ||
+                  .type != SchemaKeywordType::Reference ||
           !property.second.is_string()) {
         continue;
       }
diff --git a/src/core/jsonschema/resolver.cc b/src/core/jsonschema/resolver.cc
index 0a439ec55..41c641bf2 100644
--- a/src/core/jsonschema/resolver.cc
+++ b/src/core/jsonschema/resolver.cc
@@ -8,12 +8,12 @@
 
 namespace sourcemeta::core {
 
-MapSchemaResolver::MapSchemaResolver() {}
+SchemaMapResolver::SchemaMapResolver() {}
 
-MapSchemaResolver::MapSchemaResolver(const SchemaResolver &resolver)
+SchemaMapResolver::SchemaMapResolver(const SchemaResolver &resolver)
     : default_resolver{resolver} {}
 
-auto MapSchemaResolver::add(const JSON &schema,
+auto SchemaMapResolver::add(const JSON &schema,
                             const std::optional<std::string> &default_dialect,
                             const std::optional<std::string> &default_id)
     -> void {
@@ -21,12 +21,12 @@ auto MapSchemaResolver::add(const JSON &schema,
 
   // Registering the top-level schema is not enough. We need to check
   // and register every embedded schema resource too
-  Frame frame;
+  SchemaFrame frame;
   frame.analyse(schema, default_schema_walker, *this, default_dialect,
                 default_id);
 
   for (const auto &[key, entry] : frame.locations()) {
-    if (entry.type != Frame::LocationType::Resource) {
+    if (entry.type != SchemaFrame::LocationType::Resource) {
       continue;
     }
 
@@ -62,7 +62,7 @@ auto MapSchemaResolver::add(const JSON &schema,
   }
 }
 
-auto MapSchemaResolver::operator()(std::string_view identifier) const
+auto SchemaMapResolver::operator()(std::string_view identifier) const
     -> std::optional<JSON> {
   const std::string string_identifier{identifier};
   if (this->schemas.contains(string_identifier)) {
@@ -76,9 +76,9 @@ auto MapSchemaResolver::operator()(std::string_view identifier) const
   return std::nullopt;
 }
 
-FlatFileSchemaResolver::FlatFileSchemaResolver() {}
+SchemaFlatFileResolver::SchemaFlatFileResolver() {}
 
-FlatFileSchemaResolver::FlatFileSchemaResolver(const SchemaResolver &resolver)
+SchemaFlatFileResolver::SchemaFlatFileResolver(const SchemaResolver &resolver)
     : default_resolver{resolver} {}
 
 static auto to_lowercase(const std::string_view input) -> std::string {
@@ -90,7 +90,7 @@ static auto to_lowercase(const std::string_view input) -> std::string {
   return result;
 }
 
-auto FlatFileSchemaResolver::add(
+auto SchemaFlatFileResolver::add(
     const std::filesystem::path &path,
     const std::optional<std::string> &default_dialect,
     const std::optional<std::string> &default_id, const Reader &reader)
@@ -98,9 +98,9 @@ auto FlatFileSchemaResolver::add(
   const auto canonical{std::filesystem::weakly_canonical(path)};
   const auto schema{reader(canonical)};
   assert(sourcemeta::core::is_schema(schema));
-  const auto identifier{
-      sourcemeta::core::identify(schema, *this, IdentificationStrategy::Loose,
-                                 default_dialect, default_id)};
+  const auto identifier{sourcemeta::core::identify(
+      schema, *this, SchemaIdentificationStrategy::Loose, default_dialect,
+      default_id)};
   if (!identifier.has_value()) {
     std::ostringstream error;
     error << "Cannot identify schema: " << canonical.string();
@@ -124,7 +124,7 @@ auto FlatFileSchemaResolver::add(
   return result.first->first;
 }
 
-auto FlatFileSchemaResolver::reidentify(const std::string &schema,
+auto SchemaFlatFileResolver::reidentify(const std::string &schema,
                                         const std::string &new_identifier)
     -> void {
   const auto result{this->schemas.find(to_lowercase(schema))};
@@ -134,7 +134,7 @@ auto FlatFileSchemaResolver::reidentify(const std::string &schema,
   this->schemas.erase(result);
 }
 
-auto FlatFileSchemaResolver::operator()(std::string_view identifier) const
+auto SchemaFlatFileResolver::operator()(std::string_view identifier) const
     -> std::optional<JSON> {
   const std::string string_identifier{to_lowercase(identifier)};
   const auto result{this->schemas.find(string_identifier)};
diff --git a/src/core/jsonschema/unevaluated.cc b/src/core/jsonschema/unevaluated.cc
index e8d0220f5..d3595cf7a 100644
--- a/src/core/jsonschema/unevaluated.cc
+++ b/src/core/jsonschema/unevaluated.cc
@@ -10,13 +10,14 @@ using namespace sourcemeta::core;
 // TODO: Extract all of this into a public utility to traverse
 // adjacent subschemas
 auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
-                                const Frame &frame, const SchemaWalker &walker,
+                                const SchemaFrame &frame,
+                                const SchemaWalker &walker,
                                 const SchemaResolver &resolver,
                                 const std::set<JSON::String> &keywords,
-                                const Frame::LocationsEntry &root,
-                                const Frame::LocationsEntry &entry,
-                                const bool is_static, UnevaluatedEntry &result)
-    -> void {
+                                const SchemaFrame::LocationsEntry &root,
+                                const SchemaFrame::LocationsEntry &entry,
+                                const bool is_static,
+                                SchemaUnevaluatedEntry &result) -> void {
   const auto &subschema{get(schema, entry.pointer)};
   if (!subschema.is_object()) {
     return;
@@ -48,14 +49,14 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
 
     switch (walker(property.first, subschema_vocabularies).type) {
       // References
-      case KeywordType::Reference: {
+      case SchemaKeywordType::Reference: {
         const auto reference{frame.dereference(entry, {property.first})};
-        if (reference.first == ReferenceType::Static &&
+        if (reference.first == SchemaReferenceType::Static &&
             reference.second.has_value()) {
           find_adjacent_dependencies(
               current, schema, frame, walker, resolver, keywords, root,
               reference.second.value().get(), is_static, result);
-        } else if (reference.first == ReferenceType::Dynamic) {
+        } else if (reference.first == SchemaReferenceType::Dynamic) {
           result.unresolved = true;
         }
 
@@ -63,7 +64,7 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
       }
 
       // Static
-      case KeywordType::ApplicatorElementsInline:
+      case SchemaKeywordType::ApplicatorElementsInline:
         for (std::size_t index = 0; index < property.second.size(); index++) {
           find_adjacent_dependencies(
               current, schema, frame, walker, resolver, keywords, root,
@@ -74,7 +75,7 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
         break;
 
       // Dynamic
-      case KeywordType::ApplicatorElementsInPlace:
+      case SchemaKeywordType::ApplicatorElementsInPlace:
         if (property.second.is_array()) {
           for (std::size_t index = 0; index < property.second.size(); index++) {
             find_adjacent_dependencies(
@@ -84,7 +85,7 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
         }
 
         break;
-      case KeywordType::ApplicatorValueInPlace:
+      case SchemaKeywordType::ApplicatorValueInPlace:
         if (is_schema(property.second)) {
           find_adjacent_dependencies(
               current, schema, frame, walker, resolver, keywords, root,
@@ -92,7 +93,7 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
         }
 
         break;
-      case KeywordType::ApplicatorValueOrElementsInPlace:
+      case SchemaKeywordType::ApplicatorValueOrElementsInPlace:
         if (property.second.is_array()) {
           for (std::size_t index = 0; index < property.second.size(); index++) {
             find_adjacent_dependencies(
@@ -106,7 +107,7 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
         }
 
         break;
-      case KeywordType::ApplicatorMembersInPlace:
+      case SchemaKeywordType::ApplicatorMembersInPlace:
         if (property.second.is_object()) {
           for (const auto &pair : property.second.as_object()) {
             find_adjacent_dependencies(
@@ -129,14 +130,14 @@ auto find_adjacent_dependencies(const JSON::String &current, const JSON &schema,
 
 namespace sourcemeta::core {
 
-auto unevaluated(const JSON &schema, const Frame &frame,
+auto unevaluated(const JSON &schema, const SchemaFrame &frame,
                  const SchemaWalker &walker, const SchemaResolver &resolver)
-    -> UnevaluatedEntries {
-  UnevaluatedEntries result;
+    -> SchemaUnevaluatedEntries {
+  SchemaUnevaluatedEntries result;
 
   for (const auto &entry : frame.locations()) {
-    if (entry.second.type != Frame::LocationType::Subschema &&
-        entry.second.type != Frame::LocationType::Resource) {
+    if (entry.second.type != SchemaFrame::LocationType::Subschema &&
+        entry.second.type != SchemaFrame::LocationType::Resource) {
       continue;
     }
 
@@ -150,7 +151,7 @@ auto unevaluated(const JSON &schema, const Frame &frame,
         frame.vocabularies(entry.second, resolver)};
     for (const auto &pair : subschema.as_object()) {
       const auto keyword_uri{frame.uri(entry.second, {pair.first})};
-      UnevaluatedEntry unevaluated;
+      SchemaUnevaluatedEntry unevaluated;
       if ((subschema_vocabularies.contains(
                "https://json-schema.org/draft/2020-12/vocab/unevaluated") &&
            subschema_vocabularies.contains(
diff --git a/src/core/jsonschema/unidentify.cc b/src/core/jsonschema/unidentify.cc
index 5d341ba26..30ff4ace3 100644
--- a/src/core/jsonschema/unidentify.cc
+++ b/src/core/jsonschema/unidentify.cc
@@ -6,7 +6,7 @@ auto unidentify(JSON &schema, const SchemaWalker &walker,
                 const SchemaResolver &resolver,
                 const std::optional<std::string> &default_dialect) -> void {
   // (1) Re-frame before changing anything
-  Frame frame;
+  SchemaFrame frame;
   frame.analyse(schema, walker, resolver, default_dialect);
 
   // (2) Remove all identifiers and anchors
diff --git a/src/core/jsonschema/walker.cc b/src/core/jsonschema/walker.cc
index b12ed2240..3a81336cf 100644
--- a/src/core/jsonschema/walker.cc
+++ b/src/core/jsonschema/walker.cc
@@ -6,7 +6,7 @@
 #include <cassert>   // assert
 #include <numeric>   // std::accumulate
 
-auto sourcemeta::core::keyword_priority(
+auto sourcemeta::core::schema_keyword_priority(
     std::string_view keyword, const std::map<std::string, bool> &vocabularies,
     const sourcemeta::core::SchemaWalker &walker) -> std::uint64_t {
   const auto result{walker(keyword, vocabularies)};
@@ -14,8 +14,9 @@ auto sourcemeta::core::keyword_priority(
       result.dependencies.cbegin(), result.dependencies.cend(),
       static_cast<std::uint64_t>(0),
       [&vocabularies, &walker](const auto accumulator, const auto &dependency) {
-        return std::max(accumulator,
-                        keyword_priority(dependency, vocabularies, walker) + 1);
+        return std::max(
+            accumulator,
+            schema_keyword_priority(dependency, vocabularies, walker) + 1);
       });
 }
 
@@ -61,21 +62,21 @@ auto walk(sourcemeta::core::Pointer &pointer,
 
   for (auto &pair : subschema.as_object()) {
     switch (walker(pair.first, vocabularies).type) {
-      case sourcemeta::core::KeywordType::ApplicatorValue:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorValue:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorValueOther:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorValueOther:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorValueInPlace: {
+      case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlace: {
         sourcemeta::core::Pointer new_pointer{pointer};
         new_pointer.emplace_back(pair.first);
         walk(new_pointer, subschemas, pair.second, walker, resolver,
              new_dialect, type, level + 1);
       } break;
-      case sourcemeta::core::KeywordType::ApplicatorElements:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorElements:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorElementsInline:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsInline:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorElementsInPlace:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsInPlace:
         if (pair.second.is_array()) {
           for (std::size_t index = 0; index < pair.second.size(); index++) {
             sourcemeta::core::Pointer new_pointer{pointer};
@@ -87,11 +88,11 @@ auto walk(sourcemeta::core::Pointer &pointer,
         }
 
         break;
-      case sourcemeta::core::KeywordType::ApplicatorMembers:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorMembers:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorMembersInPlace:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorMembersInPlace:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::LocationMembers:
+      case sourcemeta::core::SchemaKeywordType::LocationMembers:
         if (pair.second.is_object()) {
           for (auto &subpair : pair.second.as_object()) {
             sourcemeta::core::Pointer new_pointer{pointer};
@@ -103,9 +104,10 @@ auto walk(sourcemeta::core::Pointer &pointer,
         }
 
         break;
-      case sourcemeta::core::KeywordType::ApplicatorValueOrElements:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorValueOrElements:
         [[fallthrough]];
-      case sourcemeta::core::KeywordType::ApplicatorValueOrElementsInPlace:
+      case sourcemeta::core::SchemaKeywordType::
+          ApplicatorValueOrElementsInPlace:
         if (pair.second.is_array()) {
           for (std::size_t index = 0; index < pair.second.size(); index++) {
             sourcemeta::core::Pointer new_pointer{pointer};
@@ -122,7 +124,7 @@ auto walk(sourcemeta::core::Pointer &pointer,
         }
 
         break;
-      case sourcemeta::core::KeywordType::ApplicatorElementsOrMembers:
+      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsOrMembers:
         if (pair.second.is_array()) {
           for (std::size_t index = 0; index < pair.second.size(); index++) {
             sourcemeta::core::Pointer new_pointer{pointer};
@@ -142,17 +144,17 @@ auto walk(sourcemeta::core::Pointer &pointer,
         }
 
         break;
-      case sourcemeta::core::KeywordType::Assertion:
+      case sourcemeta::core::SchemaKeywordType::Assertion:
         break;
-      case sourcemeta::core::KeywordType::Annotation:
+      case sourcemeta::core::SchemaKeywordType::Annotation:
         break;
-      case sourcemeta::core::KeywordType::Reference:
+      case sourcemeta::core::SchemaKeywordType::Reference:
         break;
-      case sourcemeta::core::KeywordType::Other:
+      case sourcemeta::core::SchemaKeywordType::Other:
         break;
-      case sourcemeta::core::KeywordType::Comment:
+      case sourcemeta::core::SchemaKeywordType::Comment:
         break;
-      case sourcemeta::core::KeywordType::Unknown:
+      case sourcemeta::core::SchemaKeywordType::Unknown:
         break;
     }
   }
@@ -232,9 +234,9 @@ sourcemeta::core::SchemaKeywordIterator::SchemaKeywordIterator(
         assert(!left.pointer.empty() && left.pointer.back().is_property());
         assert(!right.pointer.empty() && right.pointer.back().is_property());
 
-        const auto left_priority = keyword_priority(
+        const auto left_priority = schema_keyword_priority(
             left.pointer.back().to_property(), vocabularies, walker);
-        const auto right_priority = keyword_priority(
+        const auto right_priority = schema_keyword_priority(
             right.pointer.back().to_property(), vocabularies, walker);
 
         // Sort first on priority, second on actual keywords. The latter is to
diff --git a/test/jsonschema/jsonschema_default_walker_2019_09_test.cc b/test/jsonschema/jsonschema_default_walker_2019_09_test.cc
index 0181960d1..0c69fca59 100644
--- a/test/jsonschema/jsonschema_default_walker_2019_09_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_2019_09_test.cc
@@ -34,7 +34,7 @@ TEST(JSONSchema_default_walker_2019_09, core_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$schema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -45,7 +45,7 @@ TEST(JSONSchema_default_walker_2019_09, core_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$vocabulary", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -55,7 +55,7 @@ TEST(JSONSchema_default_walker_2019_09, core_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, core_id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$id", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -66,7 +66,7 @@ TEST(JSONSchema_default_walker_2019_09, core_anchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$anchor", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -77,7 +77,7 @@ TEST(JSONSchema_default_walker_2019_09, core_recursiveAnchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$recursiveAnchor", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -87,7 +87,7 @@ TEST(JSONSchema_default_walker_2019_09, core_recursiveAnchor) {
 TEST(JSONSchema_default_walker_2019_09, core_ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -98,7 +98,7 @@ TEST(JSONSchema_default_walker_2019_09, core_recursiveRef) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$recursiveRef", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -108,7 +108,7 @@ TEST(JSONSchema_default_walker_2019_09, core_recursiveRef) {
 TEST(JSONSchema_default_walker_2019_09, core_defs) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$defs", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::LocationMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::LocationMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -119,7 +119,7 @@ TEST(JSONSchema_default_walker_2019_09, core_comment) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$comment", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/core");
@@ -130,7 +130,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_allOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("allOf", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInline);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInline);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -141,7 +141,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_anyOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anyOf", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -152,7 +152,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_oneOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("oneOf", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -163,7 +163,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_not) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("not", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -174,7 +174,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_if) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("if", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -185,7 +185,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_then) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("then", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -197,7 +197,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_else) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("else", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -209,7 +209,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_dependentSchemas) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependentSchemas",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembersInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembersInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -220,7 +220,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_items) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("items", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -231,7 +231,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_additionalItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalItems",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -243,7 +243,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_contains_only) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contains", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -260,7 +260,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_contains_with_validation) {
             VOCABULARIES_2019_09_VALIDATION.cend(),
             std::inserter(vocabularies, vocabularies.end()));
   const auto result{default_schema_walker("contains", vocabularies)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -272,7 +272,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_properties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -283,7 +283,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_patternProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("patternProperties",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -294,7 +294,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalProperties",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -306,7 +306,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_propertyNames) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -317,7 +317,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_unevaluatedItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedItems",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -329,7 +329,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_unevaluatedProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedProperties",
                                           VOCABULARIES_2019_09_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/applicator");
@@ -342,7 +342,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_type) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("type", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -353,7 +353,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_enum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enum", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -364,7 +364,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_const) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("const", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -375,7 +375,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_multipleOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("multipleOf", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -386,7 +386,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -398,7 +398,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -410,7 +410,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("exclusiveMaximum",
                                           VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -421,7 +421,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("exclusiveMinimum",
                                           VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -432,7 +432,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maxLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -443,7 +443,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -454,7 +454,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_pattern) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -465,7 +465,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maxItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -476,7 +476,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -487,7 +487,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("uniqueItems", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -498,7 +498,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maxContains) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxContains", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -509,7 +509,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minContains) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minContains", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -520,7 +520,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maxProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -531,7 +531,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -542,7 +542,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_required) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("required", VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -553,7 +553,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_dependentRequired) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependentRequired",
                                           VOCABULARIES_2019_09_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/validation");
@@ -564,7 +564,7 @@ TEST(JSONSchema_default_walker_2019_09, format_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_2019_09_FORMAT)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/format");
@@ -575,7 +575,7 @@ TEST(JSONSchema_default_walker_2019_09, content_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_2019_09_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/content");
@@ -586,7 +586,7 @@ TEST(JSONSchema_default_walker_2019_09, content_contentMediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentMediaType", VOCABULARIES_2019_09_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/content");
@@ -597,7 +597,7 @@ TEST(JSONSchema_default_walker_2019_09, content_contentSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentSchema", VOCABULARIES_2019_09_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/content");
@@ -608,7 +608,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_title) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("title", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -619,7 +619,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_description) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -630,7 +630,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_default) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -641,7 +641,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_deprecated) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("deprecated", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -652,7 +652,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_readOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -663,7 +663,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_writeOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("writeOnly", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -674,7 +674,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_examples) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("examples", VOCABULARIES_2019_09_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/meta-data");
@@ -685,7 +685,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_base) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("base", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -694,7 +694,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -703,7 +703,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_ref) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("ref", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -712,7 +712,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -721,7 +721,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_anchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchor", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -730,7 +730,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_anchorPointer) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -739,7 +739,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -748,7 +748,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_templatePointers) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templatePointers",
                                           VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -757,7 +757,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_templateRequired) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templateRequired",
                                           VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -766,7 +766,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_targetMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetMediaType",
                                           VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -775,7 +775,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_targetHints) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetHints", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -784,7 +784,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_submissionMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionMediaType",
                                           VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -793,7 +793,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_hrefSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -804,7 +804,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -815,7 +815,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_headerSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("headerSchema", VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -826,7 +826,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_submissionSchema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionSchema",
                                           VOCABULARIES_2019_09_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -836,7 +836,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_submissionSchema) {
 TEST(JSONSchema_default_walker_2019_09, applicator_allOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("allOf", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -844,7 +844,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_allOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_anyOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anyOf", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -852,7 +852,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_anyOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_oneOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("oneOf", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -860,7 +860,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_oneOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_not_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("not", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -868,7 +868,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_not_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_if_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("if", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -876,7 +876,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_if_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_then_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("then", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -884,7 +884,7 @@ TEST(JSONSchema_default_walker_2019_09, applicator_then_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, applicator_else_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("else", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -894,7 +894,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("dependentSchemas", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -904,7 +904,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalItems", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -912,7 +912,7 @@ TEST(JSONSchema_default_walker_2019_09,
 TEST(JSONSchema_default_walker_2019_09, applicator_items_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -922,7 +922,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contains", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -932,7 +932,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -942,7 +942,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -952,7 +952,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -962,7 +962,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -972,7 +972,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("unevaluatedItems", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -982,7 +982,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedProperties",
                                           VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -990,7 +990,7 @@ TEST(JSONSchema_default_walker_2019_09,
 TEST(JSONSchema_default_walker_2019_09, validation_type_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -998,7 +998,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_type_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, validation_enum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1006,7 +1006,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_enum_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, validation_const_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("const", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1016,7 +1016,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("multipleOf", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1025,7 +1025,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_maximum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1034,7 +1034,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_minimum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1044,7 +1044,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1054,7 +1054,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1064,7 +1064,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1074,7 +1074,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1083,7 +1083,7 @@ TEST(JSONSchema_default_walker_2019_09, validation_pattern_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1093,7 +1093,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1103,7 +1103,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1113,7 +1113,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("uniqueItems", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1123,7 +1123,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxContains", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1133,7 +1133,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minContains", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1143,7 +1143,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1153,7 +1153,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1163,7 +1163,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("required", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1173,7 +1173,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("dependentRequired", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1181,7 +1181,7 @@ TEST(JSONSchema_default_walker_2019_09,
 TEST(JSONSchema_default_walker_2019_09, format_format_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1191,7 +1191,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1201,7 +1201,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentMediaType", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1211,7 +1211,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentSchema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1219,7 +1219,7 @@ TEST(JSONSchema_default_walker_2019_09,
 TEST(JSONSchema_default_walker_2019_09, metadata_title_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1229,7 +1229,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1238,7 +1238,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_default_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1248,7 +1248,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("deprecated", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1257,7 +1257,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_readOnly_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1266,7 +1266,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_writeOnly_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("writeOnly", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1275,7 +1275,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_examples_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("examples", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1283,7 +1283,7 @@ TEST(JSONSchema_default_walker_2019_09, metadata_examples_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, hyperschema_base_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("base", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1291,7 +1291,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_base_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, hyperschema_links_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1299,7 +1299,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_links_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, hyperschema_ref_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("ref", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1307,7 +1307,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_ref_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, hyperschema_href_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1315,7 +1315,7 @@ TEST(JSONSchema_default_walker_2019_09, hyperschema_href_without_vocabulary) {
 TEST(JSONSchema_default_walker_2019_09, hyperschema_anchor_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anchor", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1325,7 +1325,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1333,7 +1333,7 @@ TEST(JSONSchema_default_walker_2019_09,
 TEST(JSONSchema_default_walker_2019_09, hyperschema_rel_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1343,7 +1343,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templatePointers", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1353,7 +1353,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templateRequired", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1363,7 +1363,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetMediaType", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1373,7 +1373,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetHints", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1383,7 +1383,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionMediaType", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1393,7 +1393,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1403,7 +1403,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1413,7 +1413,7 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("headerSchema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1423,12 +1423,12 @@ TEST(JSONSchema_default_walker_2019_09,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionSchema", VOCABULARIES_2019_09_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
 
-TEST(JSONSchema_default_walker_2019_09, keyword_priority_array) {
+TEST(JSONSchema_default_walker_2019_09, schema_keyword_priority_array) {
   std::map<std::string, bool> vocabularies;
   std::copy(VOCABULARIES_2019_09_APPLICATOR.cbegin(),
             VOCABULARIES_2019_09_APPLICATOR.cend(),
@@ -1439,36 +1439,42 @@ TEST(JSONSchema_default_walker_2019_09, keyword_priority_array) {
 
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalItems", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("minContains", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("maxContains", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("contains", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("unevaluatedItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("additionalItems", vocabularies, walker),
+            1);
+  EXPECT_EQ(schema_keyword_priority("minContains", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("maxContains", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("contains", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("unevaluatedItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_2019_09, keyword_priority_object) {
+TEST(JSONSchema_default_walker_2019_09, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_2019_09_APPLICATOR;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("unevaluatedProperties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            0);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 1);
+  EXPECT_EQ(
+      schema_keyword_priority("unevaluatedProperties", vocabularies, walker),
+      2);
 }
 
-TEST(JSONSchema_default_walker_2019_09, keyword_priority_other) {
+TEST(JSONSchema_default_walker_2019_09, schema_keyword_priority_other) {
   const auto &vocabularies = VOCABULARIES_2019_09_APPLICATOR;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("if", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("then", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("else", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("if", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("then", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("else", vocabularies, walker), 1);
 }
 
-TEST(JSONSchema_default_walker_2019_09, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_2019_09, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_2019_09_CORE;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 0);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_2020_12_test.cc b/test/jsonschema/jsonschema_default_walker_2020_12_test.cc
index 660a2a816..64970888f 100644
--- a/test/jsonschema/jsonschema_default_walker_2020_12_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_2020_12_test.cc
@@ -42,7 +42,7 @@ TEST(JSONSchema_default_walker_2020_12, core_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$schema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -53,7 +53,7 @@ TEST(JSONSchema_default_walker_2020_12, core_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$vocabulary", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -63,7 +63,7 @@ TEST(JSONSchema_default_walker_2020_12, core_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, core_id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$id", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -74,7 +74,7 @@ TEST(JSONSchema_default_walker_2020_12, core_anchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$anchor", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -85,7 +85,7 @@ TEST(JSONSchema_default_walker_2020_12, core_dynamicAnchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$dynamicAnchor", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -95,7 +95,7 @@ TEST(JSONSchema_default_walker_2020_12, core_dynamicAnchor) {
 TEST(JSONSchema_default_walker_2020_12, core_ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -106,7 +106,7 @@ TEST(JSONSchema_default_walker_2020_12, core_dynamicRef) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$dynamicRef", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -116,7 +116,7 @@ TEST(JSONSchema_default_walker_2020_12, core_dynamicRef) {
 TEST(JSONSchema_default_walker_2020_12, core_defs) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$defs", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::LocationMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::LocationMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -127,7 +127,7 @@ TEST(JSONSchema_default_walker_2020_12, core_comment) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$comment", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/core");
@@ -138,7 +138,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_allOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("allOf", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInline);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInline);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -149,7 +149,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_anyOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anyOf", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -160,7 +160,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_oneOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("oneOf", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -171,7 +171,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_not) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("not", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -182,7 +182,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_if) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("if", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -193,7 +193,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_then) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("then", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -205,7 +205,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_else) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("else", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -217,7 +217,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_dependentSchemas) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependentSchemas",
                                           VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembersInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembersInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -228,7 +228,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_prefixItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("prefixItems", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -239,7 +239,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_items) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("items", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -251,7 +251,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_contains_only) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contains", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -268,7 +268,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_contains_with_validation) {
             VOCABULARIES_2020_12_VALIDATION.cend(),
             std::inserter(vocabularies, vocabularies.end()));
   const auto result{default_schema_walker("contains", vocabularies)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -280,7 +280,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_properties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -291,7 +291,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_patternProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("patternProperties",
                                           VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -302,7 +302,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalProperties",
                                           VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -314,7 +314,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_propertyNames) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_2020_12_APPLICATOR)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/applicator");
@@ -325,7 +325,7 @@ TEST(JSONSchema_default_walker_2020_12, unevaluated_unevaluatedItems_only) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedItems",
                                           VOCABULARIES_2020_12_UNEVALUATED)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/unevaluated");
@@ -343,7 +343,7 @@ TEST(JSONSchema_default_walker_2020_12,
             VOCABULARIES_2020_12_APPLICATOR.cend(),
             std::inserter(vocabularies, vocabularies.end()));
   const auto result{default_schema_walker("unevaluatedItems", vocabularies)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/unevaluated");
@@ -356,7 +356,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedProperties",
                                           VOCABULARIES_2020_12_UNEVALUATED)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/unevaluated");
@@ -375,7 +375,7 @@ TEST(JSONSchema_default_walker_2020_12,
             std::inserter(vocabularies, vocabularies.end()));
   const auto result{
       default_schema_walker("unevaluatedProperties", vocabularies)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/unevaluated");
@@ -388,7 +388,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_type) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("type", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -399,7 +399,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_enum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enum", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -410,7 +410,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_const) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("const", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -421,7 +421,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_multipleOf) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("multipleOf", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -432,7 +432,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -444,7 +444,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -456,7 +456,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("exclusiveMaximum",
                                           VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -467,7 +467,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("exclusiveMinimum",
                                           VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -478,7 +478,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maxLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -489,7 +489,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -500,7 +500,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_pattern) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -511,7 +511,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maxItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -522,7 +522,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -533,7 +533,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("uniqueItems", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -544,7 +544,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maxContains) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxContains", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -555,7 +555,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minContains) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minContains", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -566,7 +566,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maxProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -577,7 +577,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -588,7 +588,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_required) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("required", VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -599,7 +599,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_dependentRequired) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependentRequired",
                                           VOCABULARIES_2020_12_VALIDATION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/validation");
@@ -610,7 +610,7 @@ TEST(JSONSchema_default_walker_2020_12, format_annotation_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_2020_12_FORMAT_ANNOTATION)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/format-annotation");
@@ -621,7 +621,7 @@ TEST(JSONSchema_default_walker_2020_12, format_assertion_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_2020_12_FORMAT_ASSERTION)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/format-assertion");
@@ -632,7 +632,7 @@ TEST(JSONSchema_default_walker_2020_12, content_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_2020_12_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/content");
@@ -643,7 +643,7 @@ TEST(JSONSchema_default_walker_2020_12, content_contentMediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentMediaType", VOCABULARIES_2020_12_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/content");
@@ -654,7 +654,7 @@ TEST(JSONSchema_default_walker_2020_12, content_contentSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentSchema", VOCABULARIES_2020_12_CONTENT)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/content");
@@ -665,7 +665,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_title) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("title", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -676,7 +676,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_description) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -687,7 +687,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_default) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -698,7 +698,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_deprecated) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("deprecated", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -709,7 +709,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_readOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -720,7 +720,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_writeOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("writeOnly", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -731,7 +731,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_examples) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("examples", VOCABULARIES_2020_12_METADATA)};
-  EXPECT_EQ(result.type, KeywordType::Annotation);
+  EXPECT_EQ(result.type, SchemaKeywordType::Annotation);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2020-12/vocab/meta-data");
@@ -742,7 +742,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_base) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("base", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -751,7 +751,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -760,7 +760,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_ref) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("ref", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -769,7 +769,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -778,7 +778,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_anchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchor", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -787,7 +787,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_anchorPointer) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -796,7 +796,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -805,7 +805,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_templatePointers) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templatePointers",
                                           VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -814,7 +814,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_templateRequired) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templateRequired",
                                           VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -823,7 +823,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_targetMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetMediaType",
                                           VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -832,7 +832,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_targetHints) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetHints", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -841,7 +841,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_submissionMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionMediaType",
                                           VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -850,7 +850,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_hrefSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -861,7 +861,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -872,7 +872,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_headerSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("headerSchema", VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -883,7 +883,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_submissionSchema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionSchema",
                                           VOCABULARIES_2020_12_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "https://json-schema.org/draft/2019-09/vocab/hyper-schema");
@@ -893,7 +893,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_submissionSchema) {
 TEST(JSONSchema_default_walker_2020_12, applicator_allOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("allOf", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -901,7 +901,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_allOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_anyOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anyOf", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -909,7 +909,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_anyOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_oneOf_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("oneOf", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -917,7 +917,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_oneOf_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_not_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("not", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -925,7 +925,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_not_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_if_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("if", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -933,7 +933,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_if_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_then_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("then", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -941,7 +941,7 @@ TEST(JSONSchema_default_walker_2020_12, applicator_then_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, applicator_else_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("else", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -951,7 +951,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("dependentSchemas", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -961,7 +961,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("prefixItems", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -969,7 +969,7 @@ TEST(JSONSchema_default_walker_2020_12,
 TEST(JSONSchema_default_walker_2020_12, applicator_items_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -979,7 +979,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contains", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -989,7 +989,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -999,7 +999,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1009,7 +1009,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1019,7 +1019,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1029,7 +1029,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("unevaluatedItems", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1039,7 +1039,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("unevaluatedProperties",
                                           VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1047,7 +1047,7 @@ TEST(JSONSchema_default_walker_2020_12,
 TEST(JSONSchema_default_walker_2020_12, validation_type_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1055,7 +1055,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_type_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, validation_enum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1063,7 +1063,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_enum_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, validation_const_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("const", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1073,7 +1073,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("multipleOf", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1082,7 +1082,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_maximum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1091,7 +1091,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_minimum_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1101,7 +1101,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1111,7 +1111,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1121,7 +1121,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1131,7 +1131,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1140,7 +1140,7 @@ TEST(JSONSchema_default_walker_2020_12, validation_pattern_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1150,7 +1150,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1160,7 +1160,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1170,7 +1170,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("uniqueItems", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1180,7 +1180,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxContains", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1190,7 +1190,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minContains", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1200,7 +1200,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1210,7 +1210,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1220,7 +1220,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("required", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1230,7 +1230,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("dependentRequired", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1239,7 +1239,7 @@ TEST(JSONSchema_default_walker_2020_12,
      format_annotation_format_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1248,7 +1248,7 @@ TEST(JSONSchema_default_walker_2020_12,
      format_assertion_format_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1258,7 +1258,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1268,7 +1268,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentMediaType", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1278,7 +1278,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentSchema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1286,7 +1286,7 @@ TEST(JSONSchema_default_walker_2020_12,
 TEST(JSONSchema_default_walker_2020_12, metadata_title_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1296,7 +1296,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1305,7 +1305,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_default_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1315,7 +1315,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("deprecated", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1324,7 +1324,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_readOnly_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1333,7 +1333,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_writeOnly_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("writeOnly", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1342,7 +1342,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_examples_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("examples", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1350,7 +1350,7 @@ TEST(JSONSchema_default_walker_2020_12, metadata_examples_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, hyperschema_base_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("base", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1358,7 +1358,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_base_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, hyperschema_links_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1366,7 +1366,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_links_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, hyperschema_ref_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("ref", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1374,7 +1374,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_ref_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, hyperschema_href_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1382,7 +1382,7 @@ TEST(JSONSchema_default_walker_2020_12, hyperschema_href_without_vocabulary) {
 TEST(JSONSchema_default_walker_2020_12, hyperschema_anchor_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anchor", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1392,7 +1392,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1400,7 +1400,7 @@ TEST(JSONSchema_default_walker_2020_12,
 TEST(JSONSchema_default_walker_2020_12, hyperschema_rel_without_vocabulary) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1410,7 +1410,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templatePointers", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1420,7 +1420,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templateRequired", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1430,7 +1430,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetMediaType", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1440,7 +1440,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetHints", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1450,7 +1450,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionMediaType", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1460,7 +1460,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1470,7 +1470,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1480,7 +1480,7 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("headerSchema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -1490,12 +1490,12 @@ TEST(JSONSchema_default_walker_2020_12,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionSchema", VOCABULARIES_2020_12_CORE)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
 
-TEST(JSONSchema_default_walker_2020_12, keyword_priority_array) {
+TEST(JSONSchema_default_walker_2020_12, schema_keyword_priority_array) {
   std::map<std::string, bool> vocabularies;
   std::copy(VOCABULARIES_2020_12_APPLICATOR.cbegin(),
             VOCABULARIES_2020_12_APPLICATOR.cend(),
@@ -1509,15 +1509,16 @@ TEST(JSONSchema_default_walker_2020_12, keyword_priority_array) {
 
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("prefixItems", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("minContains", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("maxContains", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("contains", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("unevaluatedItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("prefixItems", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("minContains", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("maxContains", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("contains", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("unevaluatedItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_2020_12, keyword_priority_object) {
+TEST(JSONSchema_default_walker_2020_12, schema_keyword_priority_object) {
   std::map<std::string, bool> vocabularies;
   std::copy(VOCABULARIES_2020_12_APPLICATOR.cbegin(),
             VOCABULARIES_2020_12_APPLICATOR.cend(),
@@ -1528,24 +1529,28 @@ TEST(JSONSchema_default_walker_2020_12, keyword_priority_object) {
 
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("unevaluatedProperties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            0);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 1);
+  EXPECT_EQ(
+      schema_keyword_priority("unevaluatedProperties", vocabularies, walker),
+      2);
 }
 
-TEST(JSONSchema_default_walker_2020_12, keyword_priority_other) {
+TEST(JSONSchema_default_walker_2020_12, schema_keyword_priority_other) {
   const auto &vocabularies = VOCABULARIES_2020_12_APPLICATOR;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("if", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("then", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("else", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("if", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("then", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("else", vocabularies, walker), 1);
 }
 
-TEST(JSONSchema_default_walker_2020_12, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_2020_12, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_2020_12_CORE;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 0);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft0_test.cc b/test/jsonschema/jsonschema_default_walker_draft0_test.cc
index 0a13b6d86..240cdda6b 100644
--- a/test/jsonschema/jsonschema_default_walker_draft0_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft0_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT0_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft0, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -20,7 +20,7 @@ TEST(JSONSchema_default_walker_draft0, schema) {
 TEST(JSONSchema_default_walker_draft0, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("id", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -30,7 +30,7 @@ TEST(JSONSchema_default_walker_draft0, id) {
 TEST(JSONSchema_default_walker_draft0, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -40,7 +40,7 @@ TEST(JSONSchema_default_walker_draft0, ref) {
 TEST(JSONSchema_default_walker_draft0, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -50,7 +50,7 @@ TEST(JSONSchema_default_walker_draft0, items) {
 TEST(JSONSchema_default_walker_draft0, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -61,7 +61,7 @@ TEST(JSONSchema_default_walker_draft0, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -72,7 +72,7 @@ TEST(JSONSchema_default_walker_draft0, additionalProperties) {
 TEST(JSONSchema_default_walker_draft0, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -82,7 +82,7 @@ TEST(JSONSchema_default_walker_draft0, type) {
 TEST(JSONSchema_default_walker_draft0, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -92,7 +92,7 @@ TEST(JSONSchema_default_walker_draft0, enum) {
 TEST(JSONSchema_default_walker_draft0, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -102,7 +102,7 @@ TEST(JSONSchema_default_walker_draft0, maximum) {
 TEST(JSONSchema_default_walker_draft0, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -113,7 +113,7 @@ TEST(JSONSchema_default_walker_draft0, maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximumCanEqual", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -124,7 +124,7 @@ TEST(JSONSchema_default_walker_draft0, minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimumCanEqual", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -134,7 +134,7 @@ TEST(JSONSchema_default_walker_draft0, minimumCanEqual) {
 TEST(JSONSchema_default_walker_draft0, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -144,7 +144,7 @@ TEST(JSONSchema_default_walker_draft0, maxLength) {
 TEST(JSONSchema_default_walker_draft0, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -154,7 +154,7 @@ TEST(JSONSchema_default_walker_draft0, minLength) {
 TEST(JSONSchema_default_walker_draft0, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -164,7 +164,7 @@ TEST(JSONSchema_default_walker_draft0, pattern) {
 TEST(JSONSchema_default_walker_draft0, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -174,7 +174,7 @@ TEST(JSONSchema_default_walker_draft0, maxItems) {
 TEST(JSONSchema_default_walker_draft0, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -184,7 +184,7 @@ TEST(JSONSchema_default_walker_draft0, minItems) {
 TEST(JSONSchema_default_walker_draft0, requires) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("requires", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -194,7 +194,7 @@ TEST(JSONSchema_default_walker_draft0, requires) {
 TEST(JSONSchema_default_walker_draft0, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -204,7 +204,7 @@ TEST(JSONSchema_default_walker_draft0, format) {
 TEST(JSONSchema_default_walker_draft0, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -214,7 +214,7 @@ TEST(JSONSchema_default_walker_draft0, title) {
 TEST(JSONSchema_default_walker_draft0, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -224,7 +224,7 @@ TEST(JSONSchema_default_walker_draft0, description) {
 TEST(JSONSchema_default_walker_draft0, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -234,7 +234,7 @@ TEST(JSONSchema_default_walker_draft0, default) {
 TEST(JSONSchema_default_walker_draft0, disallow) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("disallow", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -244,7 +244,7 @@ TEST(JSONSchema_default_walker_draft0, disallow) {
 TEST(JSONSchema_default_walker_draft0, extends) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("extends", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -255,7 +255,7 @@ TEST(JSONSchema_default_walker_draft0, contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -265,7 +265,7 @@ TEST(JSONSchema_default_walker_draft0, contentEncoding) {
 TEST(JSONSchema_default_walker_draft0, optional) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("optional", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -275,7 +275,7 @@ TEST(JSONSchema_default_walker_draft0, optional) {
 TEST(JSONSchema_default_walker_draft0, maxDecimal) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxDecimal", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/schema#");
@@ -286,7 +286,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -295,7 +295,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_fragmentResolution) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("fragmentResolution",
                                           VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -304,7 +304,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_root) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("root", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -313,7 +313,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_readonly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readonly", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -322,7 +322,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_pathStart) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pathStart", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -331,7 +331,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -340,7 +340,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_alternate) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("alternate", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -349,7 +349,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -358,7 +358,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -367,7 +367,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_method) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("method", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -376,7 +376,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_enctype) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enctype", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -385,7 +385,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$schema", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -394,7 +394,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_id) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("id", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -403,7 +403,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_ref) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$ref", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -412,7 +412,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_items) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("items", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -423,7 +423,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_properties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -434,7 +434,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalProperties",
                                           VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -446,7 +446,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_type) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("type", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -457,7 +457,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_enum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enum", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -466,7 +466,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -475,7 +475,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_minimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -484,7 +484,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximumCanEqual",
                                           VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -493,7 +493,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimumCanEqual",
                                           VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -502,7 +502,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maxLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -511,7 +511,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_minLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -520,7 +520,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_pattern) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -529,7 +529,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maxItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -538,7 +538,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_minItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -547,7 +547,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_requires) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("requires", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -558,7 +558,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -567,7 +567,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_title) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("title", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -576,7 +576,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_description) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -585,7 +585,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_default) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -594,7 +594,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_disallow) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("disallow", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -603,7 +603,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_extends) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("extends", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-00/hyper-schema#");
@@ -614,7 +614,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contentEncoding",
                                           VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -623,7 +623,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_optional) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("optional", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -632,7 +632,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maxDecimal) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxDecimal", VOCABULARIES_DRAFT0_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -640,7 +640,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_maxDecimal) {
 TEST(JSONSchema_default_walker_draft0, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -650,7 +650,7 @@ TEST(JSONSchema_default_walker_draft0,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("fragmentResolution", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -658,7 +658,7 @@ TEST(JSONSchema_default_walker_draft0,
 TEST(JSONSchema_default_walker_draft0, hyperschema_root_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("root", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -667,7 +667,7 @@ TEST(JSONSchema_default_walker_draft0,
      hyperschema_readonly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readonly", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -676,7 +676,7 @@ TEST(JSONSchema_default_walker_draft0,
      hyperschema_pathStart_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pathStart", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -685,7 +685,7 @@ TEST(JSONSchema_default_walker_draft0,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -694,7 +694,7 @@ TEST(JSONSchema_default_walker_draft0,
      hyperschema_alternate_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("alternate", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -702,7 +702,7 @@ TEST(JSONSchema_default_walker_draft0,
 TEST(JSONSchema_default_walker_draft0, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -710,7 +710,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft0, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -718,7 +718,7 @@ TEST(JSONSchema_default_walker_draft0, hyperschema_rel_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft0, hyperschema_method_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("method", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -727,22 +727,23 @@ TEST(JSONSchema_default_walker_draft0,
      hyperschema_enctype_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enctype", VOCABULARIES_DRAFT0)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
 
-TEST(JSONSchema_default_walker_draft0, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft0, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT0;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 0);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 1);
 }
 
-TEST(JSONSchema_default_walker_draft0, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft0, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT0;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 0);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft1_test.cc b/test/jsonschema/jsonschema_default_walker_draft1_test.cc
index 813e24b04..5ec8f5da6 100644
--- a/test/jsonschema/jsonschema_default_walker_draft1_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft1_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT1_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft1, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -20,7 +20,7 @@ TEST(JSONSchema_default_walker_draft1, schema) {
 TEST(JSONSchema_default_walker_draft1, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("id", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -30,7 +30,7 @@ TEST(JSONSchema_default_walker_draft1, id) {
 TEST(JSONSchema_default_walker_draft1, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -40,7 +40,7 @@ TEST(JSONSchema_default_walker_draft1, ref) {
 TEST(JSONSchema_default_walker_draft1, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -50,7 +50,7 @@ TEST(JSONSchema_default_walker_draft1, items) {
 TEST(JSONSchema_default_walker_draft1, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -61,7 +61,7 @@ TEST(JSONSchema_default_walker_draft1, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -72,7 +72,7 @@ TEST(JSONSchema_default_walker_draft1, additionalProperties) {
 TEST(JSONSchema_default_walker_draft1, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -82,7 +82,7 @@ TEST(JSONSchema_default_walker_draft1, type) {
 TEST(JSONSchema_default_walker_draft1, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -92,7 +92,7 @@ TEST(JSONSchema_default_walker_draft1, enum) {
 TEST(JSONSchema_default_walker_draft1, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -102,7 +102,7 @@ TEST(JSONSchema_default_walker_draft1, maximum) {
 TEST(JSONSchema_default_walker_draft1, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -113,7 +113,7 @@ TEST(JSONSchema_default_walker_draft1, maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximumCanEqual", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -124,7 +124,7 @@ TEST(JSONSchema_default_walker_draft1, minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimumCanEqual", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -134,7 +134,7 @@ TEST(JSONSchema_default_walker_draft1, minimumCanEqual) {
 TEST(JSONSchema_default_walker_draft1, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -144,7 +144,7 @@ TEST(JSONSchema_default_walker_draft1, maxLength) {
 TEST(JSONSchema_default_walker_draft1, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -154,7 +154,7 @@ TEST(JSONSchema_default_walker_draft1, minLength) {
 TEST(JSONSchema_default_walker_draft1, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -164,7 +164,7 @@ TEST(JSONSchema_default_walker_draft1, pattern) {
 TEST(JSONSchema_default_walker_draft1, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -174,7 +174,7 @@ TEST(JSONSchema_default_walker_draft1, maxItems) {
 TEST(JSONSchema_default_walker_draft1, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -184,7 +184,7 @@ TEST(JSONSchema_default_walker_draft1, minItems) {
 TEST(JSONSchema_default_walker_draft1, requires) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("requires", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -194,7 +194,7 @@ TEST(JSONSchema_default_walker_draft1, requires) {
 TEST(JSONSchema_default_walker_draft1, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -204,7 +204,7 @@ TEST(JSONSchema_default_walker_draft1, format) {
 TEST(JSONSchema_default_walker_draft1, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -214,7 +214,7 @@ TEST(JSONSchema_default_walker_draft1, title) {
 TEST(JSONSchema_default_walker_draft1, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -224,7 +224,7 @@ TEST(JSONSchema_default_walker_draft1, description) {
 TEST(JSONSchema_default_walker_draft1, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -234,7 +234,7 @@ TEST(JSONSchema_default_walker_draft1, default) {
 TEST(JSONSchema_default_walker_draft1, disallow) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("disallow", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -244,7 +244,7 @@ TEST(JSONSchema_default_walker_draft1, disallow) {
 TEST(JSONSchema_default_walker_draft1, extends) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("extends", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -255,7 +255,7 @@ TEST(JSONSchema_default_walker_draft1, contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -265,7 +265,7 @@ TEST(JSONSchema_default_walker_draft1, contentEncoding) {
 TEST(JSONSchema_default_walker_draft1, optional) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("optional", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -275,7 +275,7 @@ TEST(JSONSchema_default_walker_draft1, optional) {
 TEST(JSONSchema_default_walker_draft1, maxDecimal) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxDecimal", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/schema#");
@@ -286,7 +286,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -295,7 +295,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_fragmentResolution) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("fragmentResolution",
                                           VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -304,7 +304,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_root) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("root", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -313,7 +313,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_readonly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readonly", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -322,7 +322,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_pathStart) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pathStart", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -331,7 +331,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -340,7 +340,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_alternate) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("alternate", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -349,7 +349,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -358,7 +358,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -367,7 +367,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_method) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("method", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -376,7 +376,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_enctype) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enctype", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -385,7 +385,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$schema", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -394,7 +394,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_id) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("id", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -403,7 +403,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_ref) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$ref", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -412,7 +412,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_items) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("items", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -423,7 +423,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_properties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -434,7 +434,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalProperties",
                                           VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -446,7 +446,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_type) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("type", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -457,7 +457,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_enum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enum", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -466,7 +466,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -475,7 +475,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_minimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -484,7 +484,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximumCanEqual",
                                           VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -493,7 +493,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimumCanEqual",
                                           VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -502,7 +502,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maxLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -511,7 +511,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_minLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -520,7 +520,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_pattern) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -529,7 +529,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maxItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -538,7 +538,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_minItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -547,7 +547,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_requires) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("requires", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -558,7 +558,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -567,7 +567,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_title) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("title", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -576,7 +576,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_description) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -585,7 +585,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_default) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -594,7 +594,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_disallow) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("disallow", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -603,7 +603,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_extends) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("extends", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-01/hyper-schema#");
@@ -614,7 +614,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contentEncoding",
                                           VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -623,7 +623,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_optional) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("optional", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -632,7 +632,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maxDecimal) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxDecimal", VOCABULARIES_DRAFT1_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -640,7 +640,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_maxDecimal) {
 TEST(JSONSchema_default_walker_draft1, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -650,7 +650,7 @@ TEST(JSONSchema_default_walker_draft1,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("fragmentResolution", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -658,7 +658,7 @@ TEST(JSONSchema_default_walker_draft1,
 TEST(JSONSchema_default_walker_draft1, hyperschema_root_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("root", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -667,7 +667,7 @@ TEST(JSONSchema_default_walker_draft1,
      hyperschema_readonly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readonly", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -676,7 +676,7 @@ TEST(JSONSchema_default_walker_draft1,
      hyperschema_pathStart_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pathStart", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -685,7 +685,7 @@ TEST(JSONSchema_default_walker_draft1,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -694,7 +694,7 @@ TEST(JSONSchema_default_walker_draft1,
      hyperschema_alternate_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("alternate", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -702,7 +702,7 @@ TEST(JSONSchema_default_walker_draft1,
 TEST(JSONSchema_default_walker_draft1, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -710,7 +710,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft1, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -718,7 +718,7 @@ TEST(JSONSchema_default_walker_draft1, hyperschema_rel_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft1, hyperschema_method_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("method", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -727,22 +727,23 @@ TEST(JSONSchema_default_walker_draft1,
      hyperschema_enctype_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enctype", VOCABULARIES_DRAFT1)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
 
-TEST(JSONSchema_default_walker_draft1, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft1, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT1;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 0);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 1);
 }
 
-TEST(JSONSchema_default_walker_draft1, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft1, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT1;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 0);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft2_test.cc b/test/jsonschema/jsonschema_default_walker_draft2_test.cc
index 74c77554e..8f3753eb8 100644
--- a/test/jsonschema/jsonschema_default_walker_draft2_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft2_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT2_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft2, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -20,7 +20,7 @@ TEST(JSONSchema_default_walker_draft2, schema) {
 TEST(JSONSchema_default_walker_draft2, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("id", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -30,7 +30,7 @@ TEST(JSONSchema_default_walker_draft2, id) {
 TEST(JSONSchema_default_walker_draft2, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -40,7 +40,7 @@ TEST(JSONSchema_default_walker_draft2, ref) {
 TEST(JSONSchema_default_walker_draft2, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -50,7 +50,7 @@ TEST(JSONSchema_default_walker_draft2, items) {
 TEST(JSONSchema_default_walker_draft2, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -61,7 +61,7 @@ TEST(JSONSchema_default_walker_draft2, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -72,7 +72,7 @@ TEST(JSONSchema_default_walker_draft2, additionalProperties) {
 TEST(JSONSchema_default_walker_draft2, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -82,7 +82,7 @@ TEST(JSONSchema_default_walker_draft2, type) {
 TEST(JSONSchema_default_walker_draft2, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -92,7 +92,7 @@ TEST(JSONSchema_default_walker_draft2, enum) {
 TEST(JSONSchema_default_walker_draft2, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -102,7 +102,7 @@ TEST(JSONSchema_default_walker_draft2, maximum) {
 TEST(JSONSchema_default_walker_draft2, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -113,7 +113,7 @@ TEST(JSONSchema_default_walker_draft2, maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximumCanEqual", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -124,7 +124,7 @@ TEST(JSONSchema_default_walker_draft2, minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimumCanEqual", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -134,7 +134,7 @@ TEST(JSONSchema_default_walker_draft2, minimumCanEqual) {
 TEST(JSONSchema_default_walker_draft2, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -144,7 +144,7 @@ TEST(JSONSchema_default_walker_draft2, maxLength) {
 TEST(JSONSchema_default_walker_draft2, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -154,7 +154,7 @@ TEST(JSONSchema_default_walker_draft2, minLength) {
 TEST(JSONSchema_default_walker_draft2, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -164,7 +164,7 @@ TEST(JSONSchema_default_walker_draft2, pattern) {
 TEST(JSONSchema_default_walker_draft2, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -174,7 +174,7 @@ TEST(JSONSchema_default_walker_draft2, maxItems) {
 TEST(JSONSchema_default_walker_draft2, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -184,7 +184,7 @@ TEST(JSONSchema_default_walker_draft2, minItems) {
 TEST(JSONSchema_default_walker_draft2, uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("uniqueItems", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -194,7 +194,7 @@ TEST(JSONSchema_default_walker_draft2, uniqueItems) {
 TEST(JSONSchema_default_walker_draft2, requires) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("requires", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -204,7 +204,7 @@ TEST(JSONSchema_default_walker_draft2, requires) {
 TEST(JSONSchema_default_walker_draft2, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -214,7 +214,7 @@ TEST(JSONSchema_default_walker_draft2, format) {
 TEST(JSONSchema_default_walker_draft2, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -224,7 +224,7 @@ TEST(JSONSchema_default_walker_draft2, title) {
 TEST(JSONSchema_default_walker_draft2, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -234,7 +234,7 @@ TEST(JSONSchema_default_walker_draft2, description) {
 TEST(JSONSchema_default_walker_draft2, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -244,7 +244,7 @@ TEST(JSONSchema_default_walker_draft2, default) {
 TEST(JSONSchema_default_walker_draft2, divisibleBy) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("divisibleBy", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -254,7 +254,7 @@ TEST(JSONSchema_default_walker_draft2, divisibleBy) {
 TEST(JSONSchema_default_walker_draft2, disallow) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("disallow", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -264,7 +264,7 @@ TEST(JSONSchema_default_walker_draft2, disallow) {
 TEST(JSONSchema_default_walker_draft2, extends) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("extends", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -275,7 +275,7 @@ TEST(JSONSchema_default_walker_draft2, contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/schema#");
@@ -286,7 +286,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -295,7 +295,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_fragmentResolution) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("fragmentResolution",
                                           VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -304,7 +304,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_root) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("root", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -313,7 +313,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_readonly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readonly", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -322,7 +322,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_pathStart) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pathStart", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -331,7 +331,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -340,7 +340,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_alternate) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("alternate", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -349,7 +349,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -358,7 +358,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -367,7 +367,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_method) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("method", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -376,7 +376,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_enctype) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enctype", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -385,7 +385,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -395,7 +395,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_targetSchema) {
 TEST(JSONSchema_default_walker_draft2, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -404,7 +404,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$schema", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -413,7 +413,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_id) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("id", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -422,7 +422,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_ref) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("$ref", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -431,7 +431,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_items) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("items", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -442,7 +442,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_properties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("properties", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -453,7 +453,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("additionalProperties",
                                           VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -465,7 +465,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_type) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("type", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -476,7 +476,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_enum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enum", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -485,7 +485,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_maximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maximum", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -494,7 +494,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_minimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minimum", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -503,7 +503,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_maximumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximumCanEqual",
                                           VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -512,7 +512,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_minimumCanEqual) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimumCanEqual",
                                           VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -521,7 +521,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_maxLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxLength", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -530,7 +530,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_minLength) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minLength", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -539,7 +539,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_pattern) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pattern", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -548,7 +548,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_maxItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxItems", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -557,7 +557,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_minItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minItems", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -566,7 +566,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("uniqueItems", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -575,7 +575,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_requires) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("requires", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -586,7 +586,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_format) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("format", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -595,7 +595,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_title) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("title", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -604,7 +604,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_description) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("description", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -613,7 +613,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_default) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("default", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -622,7 +622,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_divisibleBy) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("divisibleBy", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -631,7 +631,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_disallow) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("disallow", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -640,7 +640,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_extends) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("extends", VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-02/hyper-schema#");
@@ -651,7 +651,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contentEncoding",
                                           VOCABULARIES_DRAFT2_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -661,7 +661,7 @@ TEST(JSONSchema_default_walker_draft2,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("fragmentResolution", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -669,7 +669,7 @@ TEST(JSONSchema_default_walker_draft2,
 TEST(JSONSchema_default_walker_draft2, hyperschema_root_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("root", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -678,7 +678,7 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_readonly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readonly", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -687,7 +687,7 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_pathStart_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pathStart", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -696,7 +696,7 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -705,7 +705,7 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_alternate_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("alternate", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -713,7 +713,7 @@ TEST(JSONSchema_default_walker_draft2,
 TEST(JSONSchema_default_walker_draft2, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -721,7 +721,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft2, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -729,7 +729,7 @@ TEST(JSONSchema_default_walker_draft2, hyperschema_rel_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft2, hyperschema_method_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("method", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -738,7 +738,7 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_enctype_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enctype", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -747,22 +747,23 @@ TEST(JSONSchema_default_walker_draft2,
      hyperschema_targetSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetSchema", VOCABULARIES_DRAFT2)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
 
-TEST(JSONSchema_default_walker_draft2, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft2, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT2;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 0);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 0);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 1);
 }
 
-TEST(JSONSchema_default_walker_draft2, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft2, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT2;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 0);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 0);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft3_test.cc b/test/jsonschema/jsonschema_default_walker_draft3_test.cc
index ae446c66d..3d7d00c9d 100644
--- a/test/jsonschema/jsonschema_default_walker_draft3_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft3_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT3_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft3, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -21,7 +21,7 @@ TEST(JSONSchema_default_walker_draft3, schema) {
 TEST(JSONSchema_default_walker_draft3, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("id", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -32,7 +32,7 @@ TEST(JSONSchema_default_walker_draft3, id) {
 TEST(JSONSchema_default_walker_draft3, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -42,7 +42,7 @@ TEST(JSONSchema_default_walker_draft3, ref) {
 TEST(JSONSchema_default_walker_draft3, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -54,7 +54,7 @@ TEST(JSONSchema_default_walker_draft3, additionalItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalItems", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -65,7 +65,7 @@ TEST(JSONSchema_default_walker_draft3, additionalItems) {
 TEST(JSONSchema_default_walker_draft3, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -77,7 +77,7 @@ TEST(JSONSchema_default_walker_draft3, patternProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -88,7 +88,7 @@ TEST(JSONSchema_default_walker_draft3, patternProperties) {
 TEST(JSONSchema_default_walker_draft3, dependencies) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependencies", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -100,7 +100,7 @@ TEST(JSONSchema_default_walker_draft3, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -111,7 +111,7 @@ TEST(JSONSchema_default_walker_draft3, additionalProperties) {
 TEST(JSONSchema_default_walker_draft3, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -122,7 +122,7 @@ TEST(JSONSchema_default_walker_draft3, type) {
 TEST(JSONSchema_default_walker_draft3, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -133,7 +133,7 @@ TEST(JSONSchema_default_walker_draft3, enum) {
 TEST(JSONSchema_default_walker_draft3, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -144,7 +144,7 @@ TEST(JSONSchema_default_walker_draft3, maximum) {
 TEST(JSONSchema_default_walker_draft3, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -156,7 +156,7 @@ TEST(JSONSchema_default_walker_draft3, exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -168,7 +168,7 @@ TEST(JSONSchema_default_walker_draft3, exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -179,7 +179,7 @@ TEST(JSONSchema_default_walker_draft3, exclusiveMinimum) {
 TEST(JSONSchema_default_walker_draft3, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -190,7 +190,7 @@ TEST(JSONSchema_default_walker_draft3, maxLength) {
 TEST(JSONSchema_default_walker_draft3, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -201,7 +201,7 @@ TEST(JSONSchema_default_walker_draft3, minLength) {
 TEST(JSONSchema_default_walker_draft3, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -212,7 +212,7 @@ TEST(JSONSchema_default_walker_draft3, pattern) {
 TEST(JSONSchema_default_walker_draft3, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -223,7 +223,7 @@ TEST(JSONSchema_default_walker_draft3, maxItems) {
 TEST(JSONSchema_default_walker_draft3, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -234,7 +234,7 @@ TEST(JSONSchema_default_walker_draft3, minItems) {
 TEST(JSONSchema_default_walker_draft3, uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("uniqueItems", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -245,7 +245,7 @@ TEST(JSONSchema_default_walker_draft3, uniqueItems) {
 TEST(JSONSchema_default_walker_draft3, required) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("required", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -256,7 +256,7 @@ TEST(JSONSchema_default_walker_draft3, required) {
 TEST(JSONSchema_default_walker_draft3, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -267,7 +267,7 @@ TEST(JSONSchema_default_walker_draft3, format) {
 TEST(JSONSchema_default_walker_draft3, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -278,7 +278,7 @@ TEST(JSONSchema_default_walker_draft3, title) {
 TEST(JSONSchema_default_walker_draft3, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -289,7 +289,7 @@ TEST(JSONSchema_default_walker_draft3, description) {
 TEST(JSONSchema_default_walker_draft3, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -300,7 +300,7 @@ TEST(JSONSchema_default_walker_draft3, default) {
 TEST(JSONSchema_default_walker_draft3, divisibleBy) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("divisibleBy", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -311,7 +311,7 @@ TEST(JSONSchema_default_walker_draft3, divisibleBy) {
 TEST(JSONSchema_default_walker_draft3, disallow) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("disallow", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -322,7 +322,7 @@ TEST(JSONSchema_default_walker_draft3, disallow) {
 TEST(JSONSchema_default_walker_draft3, extends) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("extends", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/schema#");
@@ -334,7 +334,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -343,7 +343,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_fragmentResolution) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("fragmentResolution",
                                           VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -352,7 +352,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_root) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("root", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -361,7 +361,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_readonly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readonly", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -370,7 +370,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contentEncoding",
                                           VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -379,7 +379,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_pathStart) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pathStart", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -388,7 +388,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -397,7 +397,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_alternate) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("alternate", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -406,7 +406,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -415,7 +415,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -424,7 +424,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_method) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("method", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -433,7 +433,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_enctype) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("enctype", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   EXPECT_TRUE(result.dependencies.empty());
 }
@@ -442,7 +442,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_DRAFT3_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-03/hyper-schema#");
@@ -452,7 +452,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_targetSchema) {
 TEST(JSONSchema_default_walker_draft3, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -463,7 +463,7 @@ TEST(JSONSchema_default_walker_draft3,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("fragmentResolution", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -472,7 +472,7 @@ TEST(JSONSchema_default_walker_draft3,
 TEST(JSONSchema_default_walker_draft3, hyperschema_root_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("root", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -482,7 +482,7 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_readonly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readonly", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -493,7 +493,7 @@ TEST(JSONSchema_default_walker_draft3,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -503,7 +503,7 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_pathStart_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pathStart", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -513,7 +513,7 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -523,7 +523,7 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_alternate_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("alternate", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -532,7 +532,7 @@ TEST(JSONSchema_default_walker_draft3,
 TEST(JSONSchema_default_walker_draft3, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -541,7 +541,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft3, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -550,7 +550,7 @@ TEST(JSONSchema_default_walker_draft3, hyperschema_rel_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft3, hyperschema_method_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("method", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -560,7 +560,7 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_enctype_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enctype", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -570,32 +570,35 @@ TEST(JSONSchema_default_walker_draft3,
      hyperschema_targetSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetSchema", VOCABULARIES_DRAFT3)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
 }
 
-TEST(JSONSchema_default_walker_draft3, keyword_priority_array) {
+TEST(JSONSchema_default_walker_draft3, schema_keyword_priority_array) {
   const auto &vocabularies = VOCABULARIES_DRAFT3;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("additionalItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_draft3, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft3, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT3;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            1);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 2);
 }
 
-TEST(JSONSchema_default_walker_draft3, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft3, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT3;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 1);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft4_test.cc b/test/jsonschema/jsonschema_default_walker_draft4_test.cc
index 9615e613c..67f9f5967 100644
--- a/test/jsonschema/jsonschema_default_walker_draft4_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft4_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT4_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft4, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -21,7 +21,7 @@ TEST(JSONSchema_default_walker_draft4, schema) {
 TEST(JSONSchema_default_walker_draft4, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("id", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -32,7 +32,7 @@ TEST(JSONSchema_default_walker_draft4, id) {
 TEST(JSONSchema_default_walker_draft4, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -42,7 +42,7 @@ TEST(JSONSchema_default_walker_draft4, ref) {
 TEST(JSONSchema_default_walker_draft4, definitions) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("definitions", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::LocationMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::LocationMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -53,7 +53,7 @@ TEST(JSONSchema_default_walker_draft4, definitions) {
 TEST(JSONSchema_default_walker_draft4, allOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("allOf", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInline);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInline);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -64,7 +64,7 @@ TEST(JSONSchema_default_walker_draft4, allOf) {
 TEST(JSONSchema_default_walker_draft4, anyOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anyOf", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -75,7 +75,7 @@ TEST(JSONSchema_default_walker_draft4, anyOf) {
 TEST(JSONSchema_default_walker_draft4, oneOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("oneOf", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -86,7 +86,7 @@ TEST(JSONSchema_default_walker_draft4, oneOf) {
 TEST(JSONSchema_default_walker_draft4, not) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("not", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -97,7 +97,7 @@ TEST(JSONSchema_default_walker_draft4, not) {
 TEST(JSONSchema_default_walker_draft4, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -109,7 +109,7 @@ TEST(JSONSchema_default_walker_draft4, additionalItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalItems", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -120,7 +120,7 @@ TEST(JSONSchema_default_walker_draft4, additionalItems) {
 TEST(JSONSchema_default_walker_draft4, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -132,7 +132,7 @@ TEST(JSONSchema_default_walker_draft4, patternProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -143,7 +143,7 @@ TEST(JSONSchema_default_walker_draft4, patternProperties) {
 TEST(JSONSchema_default_walker_draft4, dependencies) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependencies", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -155,7 +155,7 @@ TEST(JSONSchema_default_walker_draft4, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -166,7 +166,7 @@ TEST(JSONSchema_default_walker_draft4, additionalProperties) {
 TEST(JSONSchema_default_walker_draft4, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -177,7 +177,7 @@ TEST(JSONSchema_default_walker_draft4, type) {
 TEST(JSONSchema_default_walker_draft4, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -188,7 +188,7 @@ TEST(JSONSchema_default_walker_draft4, enum) {
 TEST(JSONSchema_default_walker_draft4, multipleOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("multipleOf", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -199,7 +199,7 @@ TEST(JSONSchema_default_walker_draft4, multipleOf) {
 TEST(JSONSchema_default_walker_draft4, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -210,7 +210,7 @@ TEST(JSONSchema_default_walker_draft4, maximum) {
 TEST(JSONSchema_default_walker_draft4, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -222,7 +222,7 @@ TEST(JSONSchema_default_walker_draft4, exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -234,7 +234,7 @@ TEST(JSONSchema_default_walker_draft4, exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -245,7 +245,7 @@ TEST(JSONSchema_default_walker_draft4, exclusiveMinimum) {
 TEST(JSONSchema_default_walker_draft4, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -256,7 +256,7 @@ TEST(JSONSchema_default_walker_draft4, maxLength) {
 TEST(JSONSchema_default_walker_draft4, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -267,7 +267,7 @@ TEST(JSONSchema_default_walker_draft4, minLength) {
 TEST(JSONSchema_default_walker_draft4, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -278,7 +278,7 @@ TEST(JSONSchema_default_walker_draft4, pattern) {
 TEST(JSONSchema_default_walker_draft4, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -289,7 +289,7 @@ TEST(JSONSchema_default_walker_draft4, maxItems) {
 TEST(JSONSchema_default_walker_draft4, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -300,7 +300,7 @@ TEST(JSONSchema_default_walker_draft4, minItems) {
 TEST(JSONSchema_default_walker_draft4, uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("uniqueItems", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -312,7 +312,7 @@ TEST(JSONSchema_default_walker_draft4, maxProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -324,7 +324,7 @@ TEST(JSONSchema_default_walker_draft4, minProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -335,7 +335,7 @@ TEST(JSONSchema_default_walker_draft4, minProperties) {
 TEST(JSONSchema_default_walker_draft4, required) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("required", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -346,7 +346,7 @@ TEST(JSONSchema_default_walker_draft4, required) {
 TEST(JSONSchema_default_walker_draft4, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -357,7 +357,7 @@ TEST(JSONSchema_default_walker_draft4, format) {
 TEST(JSONSchema_default_walker_draft4, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -368,7 +368,7 @@ TEST(JSONSchema_default_walker_draft4, title) {
 TEST(JSONSchema_default_walker_draft4, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -379,7 +379,7 @@ TEST(JSONSchema_default_walker_draft4, description) {
 TEST(JSONSchema_default_walker_draft4, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/schema#");
@@ -391,7 +391,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -401,7 +401,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_media) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("media", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -411,7 +411,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_pathStart) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("pathStart", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -421,7 +421,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -431,7 +431,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -441,7 +441,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -451,7 +451,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_method) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("method", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -461,7 +461,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_encType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("encType", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -471,7 +471,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_readOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -481,7 +481,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/hyper-schema#");
@@ -492,7 +492,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_schema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("schema", VOCABULARIES_DRAFT4_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-04/hyper-schema#");
@@ -502,7 +502,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_schema) {
 TEST(JSONSchema_default_walker_draft4, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -511,7 +511,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_links_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft4, hyperschema_media_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("media", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -521,7 +521,7 @@ TEST(JSONSchema_default_walker_draft4,
      hyperschema_pathStart_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pathStart", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -530,7 +530,7 @@ TEST(JSONSchema_default_walker_draft4,
 TEST(JSONSchema_default_walker_draft4, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -539,7 +539,7 @@ TEST(JSONSchema_default_walker_draft4, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft4, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -549,7 +549,7 @@ TEST(JSONSchema_default_walker_draft4,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -558,7 +558,7 @@ TEST(JSONSchema_default_walker_draft4,
 TEST(JSONSchema_default_walker_draft4, hyperschema_method_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("method", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -568,7 +568,7 @@ TEST(JSONSchema_default_walker_draft4,
      hyperschema_encType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("encType", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -578,7 +578,7 @@ TEST(JSONSchema_default_walker_draft4,
      hyperschema_readOnly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readOnly", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -588,7 +588,7 @@ TEST(JSONSchema_default_walker_draft4,
      hyperschema_targetSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetSchema", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -597,32 +597,35 @@ TEST(JSONSchema_default_walker_draft4,
 TEST(JSONSchema_default_walker_draft4, hyperschema_schema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("schema", VOCABULARIES_DRAFT4)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
 }
 
-TEST(JSONSchema_default_walker_draft4, keyword_priority_array) {
+TEST(JSONSchema_default_walker_draft4, schema_keyword_priority_array) {
   const auto &vocabularies = VOCABULARIES_DRAFT4;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("additionalItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_draft4, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft4, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT4;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 2);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 3);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            1);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 3);
 }
 
-TEST(JSONSchema_default_walker_draft4, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft4, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT4;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 1);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft6_test.cc b/test/jsonschema/jsonschema_default_walker_draft6_test.cc
index ddff629ec..81bb84129 100644
--- a/test/jsonschema/jsonschema_default_walker_draft6_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft6_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT6_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft6, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -21,7 +21,7 @@ TEST(JSONSchema_default_walker_draft6, schema) {
 TEST(JSONSchema_default_walker_draft6, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$id", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -32,7 +32,7 @@ TEST(JSONSchema_default_walker_draft6, id) {
 TEST(JSONSchema_default_walker_draft6, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -42,7 +42,7 @@ TEST(JSONSchema_default_walker_draft6, ref) {
 TEST(JSONSchema_default_walker_draft6, definitions) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("definitions", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::LocationMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::LocationMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -53,7 +53,7 @@ TEST(JSONSchema_default_walker_draft6, definitions) {
 TEST(JSONSchema_default_walker_draft6, allOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("allOf", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInline);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInline);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -64,7 +64,7 @@ TEST(JSONSchema_default_walker_draft6, allOf) {
 TEST(JSONSchema_default_walker_draft6, anyOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anyOf", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -75,7 +75,7 @@ TEST(JSONSchema_default_walker_draft6, anyOf) {
 TEST(JSONSchema_default_walker_draft6, oneOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("oneOf", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -86,7 +86,7 @@ TEST(JSONSchema_default_walker_draft6, oneOf) {
 TEST(JSONSchema_default_walker_draft6, not) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("not", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -97,7 +97,7 @@ TEST(JSONSchema_default_walker_draft6, not) {
 TEST(JSONSchema_default_walker_draft6, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -109,7 +109,7 @@ TEST(JSONSchema_default_walker_draft6, additionalItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalItems", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -120,7 +120,7 @@ TEST(JSONSchema_default_walker_draft6, additionalItems) {
 TEST(JSONSchema_default_walker_draft6, contains) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contains", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -131,7 +131,7 @@ TEST(JSONSchema_default_walker_draft6, contains) {
 TEST(JSONSchema_default_walker_draft6, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -143,7 +143,7 @@ TEST(JSONSchema_default_walker_draft6, patternProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -154,7 +154,7 @@ TEST(JSONSchema_default_walker_draft6, patternProperties) {
 TEST(JSONSchema_default_walker_draft6, dependencies) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependencies", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -166,7 +166,7 @@ TEST(JSONSchema_default_walker_draft6, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -178,7 +178,7 @@ TEST(JSONSchema_default_walker_draft6, propertyNames) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -189,7 +189,7 @@ TEST(JSONSchema_default_walker_draft6, propertyNames) {
 TEST(JSONSchema_default_walker_draft6, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -200,7 +200,7 @@ TEST(JSONSchema_default_walker_draft6, type) {
 TEST(JSONSchema_default_walker_draft6, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -211,7 +211,7 @@ TEST(JSONSchema_default_walker_draft6, enum) {
 TEST(JSONSchema_default_walker_draft6, const) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("const", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -222,7 +222,7 @@ TEST(JSONSchema_default_walker_draft6, const) {
 TEST(JSONSchema_default_walker_draft6, multipleOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("multipleOf", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -233,7 +233,7 @@ TEST(JSONSchema_default_walker_draft6, multipleOf) {
 TEST(JSONSchema_default_walker_draft6, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -244,7 +244,7 @@ TEST(JSONSchema_default_walker_draft6, maximum) {
 TEST(JSONSchema_default_walker_draft6, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -256,7 +256,7 @@ TEST(JSONSchema_default_walker_draft6, exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -268,7 +268,7 @@ TEST(JSONSchema_default_walker_draft6, exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -279,7 +279,7 @@ TEST(JSONSchema_default_walker_draft6, exclusiveMinimum) {
 TEST(JSONSchema_default_walker_draft6, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -290,7 +290,7 @@ TEST(JSONSchema_default_walker_draft6, maxLength) {
 TEST(JSONSchema_default_walker_draft6, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -301,7 +301,7 @@ TEST(JSONSchema_default_walker_draft6, minLength) {
 TEST(JSONSchema_default_walker_draft6, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -312,7 +312,7 @@ TEST(JSONSchema_default_walker_draft6, pattern) {
 TEST(JSONSchema_default_walker_draft6, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -323,7 +323,7 @@ TEST(JSONSchema_default_walker_draft6, maxItems) {
 TEST(JSONSchema_default_walker_draft6, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -334,7 +334,7 @@ TEST(JSONSchema_default_walker_draft6, minItems) {
 TEST(JSONSchema_default_walker_draft6, uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("uniqueItems", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -346,7 +346,7 @@ TEST(JSONSchema_default_walker_draft6, maxProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -358,7 +358,7 @@ TEST(JSONSchema_default_walker_draft6, minProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -369,7 +369,7 @@ TEST(JSONSchema_default_walker_draft6, minProperties) {
 TEST(JSONSchema_default_walker_draft6, required) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("required", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -380,7 +380,7 @@ TEST(JSONSchema_default_walker_draft6, required) {
 TEST(JSONSchema_default_walker_draft6, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -391,7 +391,7 @@ TEST(JSONSchema_default_walker_draft6, format) {
 TEST(JSONSchema_default_walker_draft6, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -402,7 +402,7 @@ TEST(JSONSchema_default_walker_draft6, title) {
 TEST(JSONSchema_default_walker_draft6, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -413,7 +413,7 @@ TEST(JSONSchema_default_walker_draft6, description) {
 TEST(JSONSchema_default_walker_draft6, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -424,7 +424,7 @@ TEST(JSONSchema_default_walker_draft6, default) {
 TEST(JSONSchema_default_walker_draft6, examples) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("examples", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -436,7 +436,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -446,7 +446,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -456,7 +456,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -466,7 +466,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_mediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("mediaType", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -476,7 +476,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_submissionEncType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionEncType",
                                           VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -486,7 +486,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_base) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("base", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -496,7 +496,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_media) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("media", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -506,7 +506,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_readOnly) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("readOnly", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/hyper-schema#");
@@ -518,7 +518,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_hrefSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/hyper-schema#");
@@ -529,7 +529,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/hyper-schema#");
@@ -540,7 +540,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_submissionSchema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionSchema",
                                           VOCABULARIES_DRAFT6_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/hyper-schema#");
@@ -550,7 +550,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_submissionSchema) {
 TEST(JSONSchema_default_walker_draft6, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -559,7 +559,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_links_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft6, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -568,7 +568,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_href_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft6, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -578,7 +578,7 @@ TEST(JSONSchema_default_walker_draft6,
      hyperschema_mediaType_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("mediaType", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -589,7 +589,7 @@ TEST(JSONSchema_default_walker_draft6,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionEncType", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -598,7 +598,7 @@ TEST(JSONSchema_default_walker_draft6,
 TEST(JSONSchema_default_walker_draft6, hyperschema_base_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("base", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -607,7 +607,7 @@ TEST(JSONSchema_default_walker_draft6, hyperschema_base_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft6, hyperschema_media_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("media", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -617,7 +617,7 @@ TEST(JSONSchema_default_walker_draft6,
      hyperschema_readOnly_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readOnly", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-06/schema#");
@@ -629,7 +629,7 @@ TEST(JSONSchema_default_walker_draft6,
      hyperschema_hrefSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("hrefSchema", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -639,7 +639,7 @@ TEST(JSONSchema_default_walker_draft6,
      hyperschema_targetSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetSchema", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -650,32 +650,35 @@ TEST(JSONSchema_default_walker_draft6,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionSchema", VOCABULARIES_DRAFT6)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
 }
 
-TEST(JSONSchema_default_walker_draft6, keyword_priority_array) {
+TEST(JSONSchema_default_walker_draft6, schema_keyword_priority_array) {
   const auto &vocabularies = VOCABULARIES_DRAFT6;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("additionalItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_draft6, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft6, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT6;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 2);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 3);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            1);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 3);
 }
 
-TEST(JSONSchema_default_walker_draft6, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft6, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT6;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 1);
 }
diff --git a/test/jsonschema/jsonschema_default_walker_draft7_test.cc b/test/jsonschema/jsonschema_default_walker_draft7_test.cc
index 2d9871a3c..ab2c4ac35 100644
--- a/test/jsonschema/jsonschema_default_walker_draft7_test.cc
+++ b/test/jsonschema/jsonschema_default_walker_draft7_test.cc
@@ -10,7 +10,7 @@ static const std::map<std::string, bool> VOCABULARIES_DRAFT7_HYPERSCHEMA{
 TEST(JSONSchema_default_walker_draft7, schema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$schema", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -21,7 +21,7 @@ TEST(JSONSchema_default_walker_draft7, schema) {
 TEST(JSONSchema_default_walker_draft7, id) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$id", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -32,7 +32,7 @@ TEST(JSONSchema_default_walker_draft7, id) {
 TEST(JSONSchema_default_walker_draft7, ref) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$ref", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Reference);
+  EXPECT_EQ(result.type, SchemaKeywordType::Reference);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -42,7 +42,7 @@ TEST(JSONSchema_default_walker_draft7, ref) {
 TEST(JSONSchema_default_walker_draft7, definitions) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("definitions", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::LocationMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::LocationMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -53,7 +53,7 @@ TEST(JSONSchema_default_walker_draft7, definitions) {
 TEST(JSONSchema_default_walker_draft7, comment) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("$comment", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -64,7 +64,7 @@ TEST(JSONSchema_default_walker_draft7, comment) {
 TEST(JSONSchema_default_walker_draft7, allOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("allOf", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInline);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInline);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -75,7 +75,7 @@ TEST(JSONSchema_default_walker_draft7, allOf) {
 TEST(JSONSchema_default_walker_draft7, anyOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anyOf", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -86,7 +86,7 @@ TEST(JSONSchema_default_walker_draft7, anyOf) {
 TEST(JSONSchema_default_walker_draft7, oneOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("oneOf", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorElementsInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorElementsInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -97,7 +97,7 @@ TEST(JSONSchema_default_walker_draft7, oneOf) {
 TEST(JSONSchema_default_walker_draft7, not) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("not", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOther);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOther);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -108,7 +108,7 @@ TEST(JSONSchema_default_walker_draft7, not) {
 TEST(JSONSchema_default_walker_draft7, if) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("if", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -119,7 +119,7 @@ TEST(JSONSchema_default_walker_draft7, if) {
 TEST(JSONSchema_default_walker_draft7, then) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("then", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -130,7 +130,7 @@ TEST(JSONSchema_default_walker_draft7, then) {
 TEST(JSONSchema_default_walker_draft7, else) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("else", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -141,7 +141,7 @@ TEST(JSONSchema_default_walker_draft7, else) {
 TEST(JSONSchema_default_walker_draft7, items) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("items", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueOrElements);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueOrElements);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -153,7 +153,7 @@ TEST(JSONSchema_default_walker_draft7, additionalItems) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalItems", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -164,7 +164,7 @@ TEST(JSONSchema_default_walker_draft7, additionalItems) {
 TEST(JSONSchema_default_walker_draft7, contains) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("contains", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -175,7 +175,7 @@ TEST(JSONSchema_default_walker_draft7, contains) {
 TEST(JSONSchema_default_walker_draft7, properties) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("properties", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -187,7 +187,7 @@ TEST(JSONSchema_default_walker_draft7, patternProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("patternProperties", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -198,7 +198,7 @@ TEST(JSONSchema_default_walker_draft7, patternProperties) {
 TEST(JSONSchema_default_walker_draft7, dependencies) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("dependencies", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorMembers);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorMembers);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -210,7 +210,7 @@ TEST(JSONSchema_default_walker_draft7, additionalProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("additionalProperties", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -222,7 +222,7 @@ TEST(JSONSchema_default_walker_draft7, propertyNames) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("propertyNames", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValueInPlace);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValueInPlace);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -233,7 +233,7 @@ TEST(JSONSchema_default_walker_draft7, propertyNames) {
 TEST(JSONSchema_default_walker_draft7, type) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("type", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -244,7 +244,7 @@ TEST(JSONSchema_default_walker_draft7, type) {
 TEST(JSONSchema_default_walker_draft7, enum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("enum", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -255,7 +255,7 @@ TEST(JSONSchema_default_walker_draft7, enum) {
 TEST(JSONSchema_default_walker_draft7, const) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("const", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -266,7 +266,7 @@ TEST(JSONSchema_default_walker_draft7, const) {
 TEST(JSONSchema_default_walker_draft7, multipleOf) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("multipleOf", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -277,7 +277,7 @@ TEST(JSONSchema_default_walker_draft7, multipleOf) {
 TEST(JSONSchema_default_walker_draft7, maximum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maximum", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -288,7 +288,7 @@ TEST(JSONSchema_default_walker_draft7, maximum) {
 TEST(JSONSchema_default_walker_draft7, minimum) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minimum", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -300,7 +300,7 @@ TEST(JSONSchema_default_walker_draft7, exclusiveMaximum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMaximum", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -312,7 +312,7 @@ TEST(JSONSchema_default_walker_draft7, exclusiveMinimum) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("exclusiveMinimum", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -323,7 +323,7 @@ TEST(JSONSchema_default_walker_draft7, exclusiveMinimum) {
 TEST(JSONSchema_default_walker_draft7, maxLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxLength", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -334,7 +334,7 @@ TEST(JSONSchema_default_walker_draft7, maxLength) {
 TEST(JSONSchema_default_walker_draft7, minLength) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minLength", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -345,7 +345,7 @@ TEST(JSONSchema_default_walker_draft7, minLength) {
 TEST(JSONSchema_default_walker_draft7, pattern) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("pattern", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -356,7 +356,7 @@ TEST(JSONSchema_default_walker_draft7, pattern) {
 TEST(JSONSchema_default_walker_draft7, maxItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("maxItems", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -367,7 +367,7 @@ TEST(JSONSchema_default_walker_draft7, maxItems) {
 TEST(JSONSchema_default_walker_draft7, minItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("minItems", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -378,7 +378,7 @@ TEST(JSONSchema_default_walker_draft7, minItems) {
 TEST(JSONSchema_default_walker_draft7, uniqueItems) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("uniqueItems", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -390,7 +390,7 @@ TEST(JSONSchema_default_walker_draft7, maxProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("maxProperties", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -402,7 +402,7 @@ TEST(JSONSchema_default_walker_draft7, minProperties) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("minProperties", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -413,7 +413,7 @@ TEST(JSONSchema_default_walker_draft7, minProperties) {
 TEST(JSONSchema_default_walker_draft7, required) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("required", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Assertion);
+  EXPECT_EQ(result.type, SchemaKeywordType::Assertion);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -424,7 +424,7 @@ TEST(JSONSchema_default_walker_draft7, required) {
 TEST(JSONSchema_default_walker_draft7, format) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("format", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Other);
+  EXPECT_EQ(result.type, SchemaKeywordType::Other);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -436,7 +436,7 @@ TEST(JSONSchema_default_walker_draft7, contentEncoding) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentEncoding", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -448,7 +448,7 @@ TEST(JSONSchema_default_walker_draft7, contentMediaType) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("contentMediaType", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -459,7 +459,7 @@ TEST(JSONSchema_default_walker_draft7, contentMediaType) {
 TEST(JSONSchema_default_walker_draft7, title) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("title", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -470,7 +470,7 @@ TEST(JSONSchema_default_walker_draft7, title) {
 TEST(JSONSchema_default_walker_draft7, description) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("description", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -481,7 +481,7 @@ TEST(JSONSchema_default_walker_draft7, description) {
 TEST(JSONSchema_default_walker_draft7, default) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("default", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -492,7 +492,7 @@ TEST(JSONSchema_default_walker_draft7, default) {
 TEST(JSONSchema_default_walker_draft7, readOnly) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("readOnly", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -503,7 +503,7 @@ TEST(JSONSchema_default_walker_draft7, readOnly) {
 TEST(JSONSchema_default_walker_draft7, writeOnly) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("writeOnly", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -514,7 +514,7 @@ TEST(JSONSchema_default_walker_draft7, writeOnly) {
 TEST(JSONSchema_default_walker_draft7, examples) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("examples", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Comment);
+  EXPECT_EQ(result.type, SchemaKeywordType::Comment);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/schema#");
@@ -526,7 +526,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_links) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("links", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -536,7 +536,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_base) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("base", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -546,7 +546,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_anchor) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchor", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -556,7 +556,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_anchorPointer) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -566,7 +566,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_rel) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("rel", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -576,7 +576,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_href) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("href", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -586,7 +586,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_templatePointers) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templatePointers",
                                           VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -596,7 +596,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_templateRequired) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("templateRequired",
                                           VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -606,7 +606,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_targetMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetMediaType",
                                           VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -616,7 +616,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_targetHints) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetHints", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -626,7 +626,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_submissionMediaType) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionMediaType",
                                           VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -636,7 +636,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_hrefSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("hrefSchema", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/hyper-schema#");
@@ -647,7 +647,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_targetSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetSchema", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/hyper-schema#");
@@ -658,7 +658,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_headerSchema) {
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("headerSchema", VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/hyper-schema#");
@@ -669,7 +669,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_submissionSchema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("submissionSchema",
                                           VOCABULARIES_DRAFT7_HYPERSCHEMA)};
-  EXPECT_EQ(result.type, KeywordType::ApplicatorValue);
+  EXPECT_EQ(result.type, SchemaKeywordType::ApplicatorValue);
   EXPECT_TRUE(result.vocabulary.has_value());
   EXPECT_EQ(result.vocabulary.value(),
             "http://json-schema.org/draft-07/hyper-schema#");
@@ -679,7 +679,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_submissionSchema) {
 TEST(JSONSchema_default_walker_draft7, hyperschema_links_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("links", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -688,7 +688,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_links_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft7, hyperschema_base_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("base", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -697,7 +697,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_base_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft7, hyperschema_anchor_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("anchor", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -708,7 +708,7 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("anchorPointer", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -717,7 +717,7 @@ TEST(JSONSchema_default_walker_draft7,
 TEST(JSONSchema_default_walker_draft7, hyperschema_rel_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("rel", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -726,7 +726,7 @@ TEST(JSONSchema_default_walker_draft7, hyperschema_rel_without_hyperschema) {
 TEST(JSONSchema_default_walker_draft7, hyperschema_href_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("href", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -737,7 +737,7 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templatePointers", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -748,7 +748,7 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("templateRequired", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -759,7 +759,7 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("targetMediaType", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -769,7 +769,7 @@ TEST(JSONSchema_default_walker_draft7,
      hyperschema_targetHints_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetHints", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -780,7 +780,7 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionMediaType", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -790,7 +790,7 @@ TEST(JSONSchema_default_walker_draft7,
      hyperschema_hrefSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("hrefSchema", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -800,7 +800,7 @@ TEST(JSONSchema_default_walker_draft7,
      hyperschema_targetSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("targetSchema", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -810,7 +810,7 @@ TEST(JSONSchema_default_walker_draft7,
      hyperschema_headerSchema_without_hyperschema) {
   using namespace sourcemeta::core;
   const auto result{default_schema_walker("headerSchema", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
@@ -821,41 +821,44 @@ TEST(JSONSchema_default_walker_draft7,
   using namespace sourcemeta::core;
   const auto result{
       default_schema_walker("submissionSchema", VOCABULARIES_DRAFT7)};
-  EXPECT_EQ(result.type, KeywordType::Unknown);
+  EXPECT_EQ(result.type, SchemaKeywordType::Unknown);
   EXPECT_FALSE(result.vocabulary.has_value());
   const std::set<std::string> expected{"$ref"};
   EXPECT_EQ(result.dependencies, expected);
 }
 
-TEST(JSONSchema_default_walker_draft7, keyword_priority_array) {
+TEST(JSONSchema_default_walker_draft7, schema_keyword_priority_array) {
   const auto &vocabularies = VOCABULARIES_DRAFT7;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("items", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalItems", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("items", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("additionalItems", vocabularies, walker),
+            2);
 }
 
-TEST(JSONSchema_default_walker_draft7, keyword_priority_object) {
+TEST(JSONSchema_default_walker_draft7, schema_keyword_priority_object) {
   const auto &vocabularies = VOCABULARIES_DRAFT7;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("properties", vocabularies, walker), 2);
-  EXPECT_EQ(keyword_priority("patternProperties", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("additionalProperties", vocabularies, walker), 3);
+  EXPECT_EQ(schema_keyword_priority("properties", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("patternProperties", vocabularies, walker),
+            1);
+  EXPECT_EQ(
+      schema_keyword_priority("additionalProperties", vocabularies, walker), 3);
 }
 
-TEST(JSONSchema_default_walker_draft7, keyword_priority_other) {
+TEST(JSONSchema_default_walker_draft7, schema_keyword_priority_other) {
   const auto &vocabularies = VOCABULARIES_DRAFT7;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("if", vocabularies, walker), 1);
-  EXPECT_EQ(keyword_priority("then", vocabularies, walker), 2);
-  EXPECT_EQ(keyword_priority("else", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("if", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("then", vocabularies, walker), 2);
+  EXPECT_EQ(schema_keyword_priority("else", vocabularies, walker), 2);
 }
 
-TEST(JSONSchema_default_walker_draft7, keyword_priority_unknown) {
+TEST(JSONSchema_default_walker_draft7, schema_keyword_priority_unknown) {
   const auto &vocabularies = VOCABULARIES_DRAFT7;
   const auto &walker = sourcemeta::core::default_schema_walker;
   using namespace sourcemeta::core;
-  EXPECT_EQ(keyword_priority("foobar", vocabularies, walker), 1);
+  EXPECT_EQ(schema_keyword_priority("foobar", vocabularies, walker), 1);
 }
diff --git a/test/jsonschema/jsonschema_flat_file_resolver_test.cc b/test/jsonschema/jsonschema_flat_file_resolver_test.cc
index 4672fd729..010076f0e 100644
--- a/test/jsonschema/jsonschema_flat_file_resolver_test.cc
+++ b/test/jsonschema/jsonschema_flat_file_resolver_test.cc
@@ -2,14 +2,14 @@
 
 #include <sourcemeta/core/jsonschema.h>
 
-TEST(JSONSchema_FlatFileSchemaResolver, empty_no_fallback) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, empty_no_fallback) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   EXPECT_FALSE(
       resolver("https://json-schema.org/draft/2020-12/schema").has_value());
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, empty_with_fallback) {
-  sourcemeta::core::FlatFileSchemaResolver resolver{
+TEST(JSONSchema_SchemaFlatFileResolver, empty_with_fallback) {
+  sourcemeta::core::SchemaFlatFileResolver resolver{
       sourcemeta::core::official_resolver};
   EXPECT_TRUE(
       resolver("https://json-schema.org/draft/2020-12/schema").has_value());
@@ -18,8 +18,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, empty_with_fallback) {
                 "https://json-schema.org/draft/2020-12/schema"));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, single_schema) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, single_schema) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id.json"};
   const auto &identifier{resolver.add(schema_path)};
@@ -30,8 +30,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema) {
             sourcemeta::core::read_json(schema_path));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, single_schema_custom_reader) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, single_schema_custom_reader) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-id"};
   const auto &identifier{resolver.add(
       schema_path, std::nullopt, std::nullopt, [](const auto &path) {
@@ -44,8 +44,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_custom_reader) {
             sourcemeta::core::read_json(schema_path.string() + ".json"));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, single_schema_with_default_dialect) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, single_schema_with_default_dialect) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "only-id.json"};
 
   const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
@@ -61,8 +61,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_with_default_dialect) {
             expected);
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, single_schema_anonymous_with_default) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, single_schema_anonymous_with_default) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-anonymous.json"};
 
@@ -78,8 +78,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_anonymous_with_default) {
   EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), expected);
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, single_schema_idempotent) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, single_schema_idempotent) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id.json"};
 
@@ -97,8 +97,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_idempotent) {
             sourcemeta::core::read_json(schema_path));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, duplicate_ids) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, duplicate_ids) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
 
   const auto schema_path_1{std::filesystem::path{SCHEMAS_PATH} /
                            "2020-12-id.json"};
@@ -110,8 +110,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, duplicate_ids) {
   EXPECT_THROW(resolver.add(schema_path_2), sourcemeta::core::SchemaError);
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, no_embedded_resource) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, no_embedded_resource) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-embedded.json"};
 
@@ -126,8 +126,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, no_embedded_resource) {
   EXPECT_FALSE(resolver("https://www.sourcemeta.com/string").has_value());
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, metaschema_out_of_order) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, metaschema_out_of_order) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-meta-1-schema.json"};
   const auto metaschema_path{std::filesystem::path{SCHEMAS_PATH} /
@@ -159,15 +159,15 @@ TEST(JSONSchema_FlatFileSchemaResolver, metaschema_out_of_order) {
       sourcemeta::core::read_json(schema_path));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, iterators) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, iterators) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id.json"};
   const auto &identifier{resolver.add(schema_path)};
   EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-id.json");
 
   std::vector<std::string> identifiers;
-  std::vector<sourcemeta::core::FlatFileSchemaResolver::Entry> entries;
+  std::vector<sourcemeta::core::SchemaFlatFileResolver::Entry> entries;
   for (const auto &entry : resolver) {
     identifiers.push_back(entry.first);
     entries.push_back(entry.second);
@@ -181,8 +181,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, iterators) {
   EXPECT_FALSE(entries.at(0).default_dialect.has_value());
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, reidentify) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, reidentify) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id.json"};
   const auto &identifier{resolver.add(schema_path)};
@@ -207,8 +207,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, reidentify) {
   EXPECT_EQ(resolver("https://example.com").value(), expected);
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, with_absolute_references) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, with_absolute_references) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-absolute-ref.json"};
 
@@ -227,8 +227,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, with_absolute_references) {
       expected);
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_lookup) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, case_insensitive_lookup) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id.json"};
   const auto &identifier{resolver.add(schema_path)};
@@ -243,8 +243,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_lookup) {
             sourcemeta::core::read_json(schema_path));
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_insert) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, case_insensitive_insert) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id-casing.json"};
   const auto &identifier{resolver.add(schema_path)};
@@ -259,8 +259,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_insert) {
       resolver("https://www.SOURCEMETA.com/2020-12-id.json").has_value());
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_reidentify) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, case_insensitive_reidentify) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2020-12-id-casing.json"};
   const auto &identifier{resolver.add(schema_path)};
@@ -269,8 +269,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, case_insensitive_reidentify) {
   EXPECT_TRUE(resolver("https://example.com").has_value());
 }
 
-TEST(JSONSchema_FlatFileSchemaResolver, with_recursive_ref) {
-  sourcemeta::core::FlatFileSchemaResolver resolver;
+TEST(JSONSchema_SchemaFlatFileResolver, with_recursive_ref) {
+  sourcemeta::core::SchemaFlatFileResolver resolver;
   const auto schema_path{std::filesystem::path{SCHEMAS_PATH} /
                          "2019-09-recursive-ref.json"};
 
diff --git a/test/jsonschema/jsonschema_frame_2019_09_test.cc b/test/jsonschema/jsonschema_frame_2019_09_test.cc
index 23eab355f..ca66ad119 100644
--- a/test/jsonschema/jsonschema_frame_2019_09_test.cc
+++ b/test/jsonschema/jsonschema_frame_2019_09_test.cc
@@ -57,7 +57,7 @@ TEST(JSONSchema_frame_2019_09, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "$id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -105,7 +105,7 @@ TEST(JSONSchema_frame_2019_09, empty_schema) {
     "$schema": "https://json-schema.org/draft/2019-09/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -145,7 +145,7 @@ TEST(JSONSchema_frame_2019_09, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -205,7 +205,7 @@ TEST(JSONSchema_frame_2019_09, one_level_applicators_with_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -294,7 +294,7 @@ TEST(JSONSchema_frame_2019_09, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -372,7 +372,7 @@ TEST(JSONSchema_frame_2019_09, nested_schemas) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -526,7 +526,7 @@ TEST(JSONSchema_frame_2019_09, id_override) {
     "items": { "$id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -540,7 +540,7 @@ TEST(JSONSchema_frame_2019_09, static_anchor_override) {
     "items": { "$anchor": "foo" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -552,7 +552,7 @@ TEST(JSONSchema_frame_2019_09, explicit_argument_id_same) {
     "$schema": "https://json-schema.org/draft/2019-09/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "https://json-schema.org/draft/2019-09/schema",
@@ -591,7 +591,7 @@ TEST(JSONSchema_frame_2019_09, anchor_top_level) {
     "$anchor": "foo"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -649,7 +649,7 @@ TEST(JSONSchema_frame_2019_09, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "https://json-schema.org/draft/2019-09/schema",
@@ -774,7 +774,7 @@ TEST(JSONSchema_frame_2019_09, ref_metaschema) {
     "$ref": "https://json-schema.org/draft/2019-09/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -816,7 +816,7 @@ TEST(JSONSchema_frame_2019_09, location_independent_identifier_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
 
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
@@ -830,7 +830,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_true_with_id) {
     "$recursiveAnchor": true
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -881,7 +881,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_false_with_id) {
     "$recursiveAnchor": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -928,7 +928,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_true_without_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -983,7 +983,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_false_without_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1029,7 +1029,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_no_recursive_anchor_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1072,7 +1072,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_no_recursive_anchor) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1121,7 +1121,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_recursive_anchor_false_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1169,7 +1169,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_recursive_anchor_false) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1222,7 +1222,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_recursive_anchor_true_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1276,7 +1276,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_recursive_anchor_true) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1338,7 +1338,7 @@ TEST(JSONSchema_frame_2019_09,
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1413,7 +1413,7 @@ TEST(JSONSchema_frame_2019_09,
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1494,7 +1494,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_nested_recursive_anchor_true) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1559,7 +1559,7 @@ TEST(JSONSchema_frame_2019_09, recursive_ref_multiple_recursive_anchor_true) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1650,7 +1650,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_conflict) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -1663,7 +1663,7 @@ TEST(JSONSchema_frame_2019_09, invalid_recursive_ref) {
     "$recursiveRef": "nested#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -1679,7 +1679,7 @@ TEST(JSONSchema_frame_2019_09, recursive_anchor_on_relative_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1754,7 +1754,7 @@ TEST(JSONSchema_frame_2019_09, ref_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1815,7 +1815,7 @@ TEST(JSONSchema_frame_2019_09, ref_from_definitions) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1883,7 +1883,7 @@ TEST(JSONSchema_frame_2019_09, relative_base_uri_without_ref) {
     "$id": "common"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1920,7 +1920,7 @@ TEST(JSONSchema_frame_2019_09, relative_base_uri_with_ref) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1972,7 +1972,7 @@ TEST(JSONSchema_frame_2019_09, relative_id_leading_slash) {
     "$schema": "https://json-schema.org/draft/2019-09/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_2020_12_test.cc b/test/jsonschema/jsonschema_frame_2020_12_test.cc
index 8000ae466..652c50063 100644
--- a/test/jsonschema/jsonschema_frame_2020_12_test.cc
+++ b/test/jsonschema/jsonschema_frame_2020_12_test.cc
@@ -57,7 +57,7 @@ TEST(JSONSchema_frame_2020_12, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "$id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -105,7 +105,7 @@ TEST(JSONSchema_frame_2020_12, empty_schema) {
     "$schema": "https://json-schema.org/draft/2020-12/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -145,7 +145,7 @@ TEST(JSONSchema_frame_2020_12, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -205,7 +205,7 @@ TEST(JSONSchema_frame_2020_12, one_level_applicators_with_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -293,7 +293,7 @@ TEST(JSONSchema_frame_2020_12, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -363,7 +363,7 @@ TEST(JSONSchema_frame_2020_12, nested_schemas) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -517,7 +517,7 @@ TEST(JSONSchema_frame_2020_12, id_override) {
     "items": { "$id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -531,7 +531,7 @@ TEST(JSONSchema_frame_2020_12, static_anchor_override) {
     "items": { "$anchor": "foo" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -543,7 +543,7 @@ TEST(JSONSchema_frame_2020_12, explicit_argument_id_same) {
     "$schema": "https://json-schema.org/draft/2020-12/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "https://json-schema.org/draft/2020-12/schema",
@@ -582,7 +582,7 @@ TEST(JSONSchema_frame_2020_12, anchor_top_level) {
     "$anchor": "foo"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -640,7 +640,7 @@ TEST(JSONSchema_frame_2020_12, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "https://json-schema.org/draft/2020-12/schema",
@@ -789,7 +789,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_refs_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -849,7 +849,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_refs_with_no_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -889,7 +889,7 @@ TEST(JSONSchema_frame_2020_12, ref_to_dynamic_anchor) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -915,7 +915,7 @@ TEST(JSONSchema_frame_2020_12, different_dynamic_and_refs_in_same_object) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -949,7 +949,7 @@ TEST(JSONSchema_frame_2020_12, same_dynamic_and_refs_in_same_object) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -986,7 +986,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_anchor_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1107,7 +1107,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_anchor_without_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1168,7 +1168,7 @@ TEST(JSONSchema_frame_2020_12,
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1235,7 +1235,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_ref_to_single_dynamic_anchor_external) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1309,7 +1309,7 @@ TEST(JSONSchema_frame_2020_12, dynamic_anchor_same_on_schema_resource) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -1325,7 +1325,7 @@ TEST(JSONSchema_frame_2020_12, no_id_recursive_empty_pointer) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1368,7 +1368,7 @@ TEST(JSONSchema_frame_2020_12, ref_metaschema) {
     "$ref": "https://json-schema.org/draft/2020-12/schema"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1410,7 +1410,7 @@ TEST(JSONSchema_frame_2020_12, location_independent_identifier_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
 
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
@@ -1427,7 +1427,7 @@ TEST(JSONSchema_frame_2020_12, ref_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1488,7 +1488,7 @@ TEST(JSONSchema_frame_2020_12, ref_from_definitions) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1556,7 +1556,7 @@ TEST(JSONSchema_frame_2020_12, relative_base_uri_without_ref) {
     "$id": "common"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1593,7 +1593,7 @@ TEST(JSONSchema_frame_2020_12, relative_base_uri_with_ref) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -1649,7 +1649,7 @@ TEST(JSONSchema_frame_2020_12, idempotent_with_refs) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
 
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
@@ -1709,7 +1709,7 @@ TEST(JSONSchema_frame_2020_12, allof_refs) {
     ]
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft0_test.cc b/test/jsonschema/jsonschema_frame_draft0_test.cc
index b7efebd54..6c682602d 100644
--- a/test/jsonschema/jsonschema_frame_draft0_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft0_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_frame_draft0, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -86,7 +86,7 @@ TEST(JSONSchema_frame_draft0, empty_schema) {
     "$schema": "http://json-schema.org/draft-00/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -126,7 +126,7 @@ TEST(JSONSchema_frame_draft0, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -183,7 +183,7 @@ TEST(JSONSchema_frame_draft0, one_level_applicators_with_identifiers) {
     "items": { "id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -247,7 +247,7 @@ TEST(JSONSchema_frame_draft0, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -308,7 +308,7 @@ TEST(JSONSchema_frame_draft0, id_override) {
     "items": { "id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -320,7 +320,7 @@ TEST(JSONSchema_frame_draft0, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-00/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-00/schema#",
@@ -366,7 +366,7 @@ TEST(JSONSchema_frame_draft0, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-00/schema#",
@@ -446,7 +446,7 @@ TEST(JSONSchema_frame_draft0, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-00/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft1_test.cc b/test/jsonschema/jsonschema_frame_draft1_test.cc
index 9560ef342..6140abefb 100644
--- a/test/jsonschema/jsonschema_frame_draft1_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft1_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_frame_draft1, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -86,7 +86,7 @@ TEST(JSONSchema_frame_draft1, empty_schema) {
     "$schema": "http://json-schema.org/draft-01/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -126,7 +126,7 @@ TEST(JSONSchema_frame_draft1, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -183,7 +183,7 @@ TEST(JSONSchema_frame_draft1, one_level_applicators_with_identifiers) {
     "items": { "id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -247,7 +247,7 @@ TEST(JSONSchema_frame_draft1, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -308,7 +308,7 @@ TEST(JSONSchema_frame_draft1, id_override) {
     "items": { "id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -320,7 +320,7 @@ TEST(JSONSchema_frame_draft1, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-01/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-01/schema#",
@@ -366,7 +366,7 @@ TEST(JSONSchema_frame_draft1, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-01/schema#",
@@ -446,7 +446,7 @@ TEST(JSONSchema_frame_draft1, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-01/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft2_test.cc b/test/jsonschema/jsonschema_frame_draft2_test.cc
index 27583f41d..3781f46da 100644
--- a/test/jsonschema/jsonschema_frame_draft2_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft2_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_frame_draft2, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -86,7 +86,7 @@ TEST(JSONSchema_frame_draft2, empty_schema) {
     "$schema": "http://json-schema.org/draft-02/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -126,7 +126,7 @@ TEST(JSONSchema_frame_draft2, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -183,7 +183,7 @@ TEST(JSONSchema_frame_draft2, one_level_applicators_with_identifiers) {
     "items": { "id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -247,7 +247,7 @@ TEST(JSONSchema_frame_draft2, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -308,7 +308,7 @@ TEST(JSONSchema_frame_draft2, id_override) {
     "items": { "id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -320,7 +320,7 @@ TEST(JSONSchema_frame_draft2, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-02/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-02/schema#",
@@ -366,7 +366,7 @@ TEST(JSONSchema_frame_draft2, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-02/schema#",
@@ -446,7 +446,7 @@ TEST(JSONSchema_frame_draft2, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-02/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft3_test.cc b/test/jsonschema/jsonschema_frame_draft3_test.cc
index 990a5d123..43403cde5 100644
--- a/test/jsonschema/jsonschema_frame_draft3_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft3_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_frame_draft3, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -86,7 +86,7 @@ TEST(JSONSchema_frame_draft3, empty_schema) {
     "$schema": "http://json-schema.org/draft-03/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -126,7 +126,7 @@ TEST(JSONSchema_frame_draft3, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -183,7 +183,7 @@ TEST(JSONSchema_frame_draft3, one_level_applicators_with_identifiers) {
     "items": { "id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -247,7 +247,7 @@ TEST(JSONSchema_frame_draft3, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -308,7 +308,7 @@ TEST(JSONSchema_frame_draft3, id_override) {
     "items": { "id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -320,7 +320,7 @@ TEST(JSONSchema_frame_draft3, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-03/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-03/schema#",
@@ -366,7 +366,7 @@ TEST(JSONSchema_frame_draft3, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-03/schema#",
@@ -446,7 +446,7 @@ TEST(JSONSchema_frame_draft3, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-03/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -481,7 +481,7 @@ TEST(JSONSchema_frame_draft3, ref_with_id) {
     "$ref": "#/definitions/string"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft4_test.cc b/test/jsonschema/jsonschema_frame_draft4_test.cc
index 5cb1a6796..02f953d40 100644
--- a/test/jsonschema/jsonschema_frame_draft4_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft4_test.cc
@@ -48,7 +48,7 @@ TEST(JSONSchema_frame_draft4, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -95,7 +95,7 @@ TEST(JSONSchema_frame_draft4, empty_schema) {
     "$schema": "http://json-schema.org/draft-04/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -135,7 +135,7 @@ TEST(JSONSchema_frame_draft4, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -192,7 +192,7 @@ TEST(JSONSchema_frame_draft4, one_level_applicators_with_identifiers) {
     "items": { "id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -256,7 +256,7 @@ TEST(JSONSchema_frame_draft4, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -317,7 +317,7 @@ TEST(JSONSchema_frame_draft4, id_override) {
     "items": { "id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -329,7 +329,7 @@ TEST(JSONSchema_frame_draft4, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-04/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-04/schema#",
@@ -375,7 +375,7 @@ TEST(JSONSchema_frame_draft4, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-04/schema#",
@@ -455,7 +455,7 @@ TEST(JSONSchema_frame_draft4, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-04/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -496,7 +496,7 @@ TEST(JSONSchema_frame_draft4, location_independent_identifier_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -561,7 +561,7 @@ TEST(JSONSchema_frame_draft4, ref_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -611,7 +611,7 @@ TEST(JSONSchema_frame_draft4, relative_base_uri_without_ref) {
     "id": "common"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -648,7 +648,7 @@ TEST(JSONSchema_frame_draft4, relative_base_uri_with_ref) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft6_test.cc b/test/jsonschema/jsonschema_frame_draft6_test.cc
index a956ab762..a102c7c4f 100644
--- a/test/jsonschema/jsonschema_frame_draft6_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft6_test.cc
@@ -48,7 +48,7 @@ TEST(JSONSchema_frame_draft6, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "$id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -95,7 +95,7 @@ TEST(JSONSchema_frame_draft6, empty_schema) {
     "$schema": "http://json-schema.org/draft-06/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -135,7 +135,7 @@ TEST(JSONSchema_frame_draft6, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -192,7 +192,7 @@ TEST(JSONSchema_frame_draft6, one_level_applicators_with_identifiers) {
     "items": { "$id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -256,7 +256,7 @@ TEST(JSONSchema_frame_draft6, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -317,7 +317,7 @@ TEST(JSONSchema_frame_draft6, id_override) {
     "items": { "$id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -329,7 +329,7 @@ TEST(JSONSchema_frame_draft6, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-06/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-06/schema#",
@@ -375,7 +375,7 @@ TEST(JSONSchema_frame_draft6, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-06/schema#",
@@ -455,7 +455,7 @@ TEST(JSONSchema_frame_draft6, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-06/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -496,7 +496,7 @@ TEST(JSONSchema_frame_draft6, location_independent_identifier_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -561,7 +561,7 @@ TEST(JSONSchema_frame_draft6, ref_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -611,7 +611,7 @@ TEST(JSONSchema_frame_draft6, relative_base_uri_without_ref) {
     "$id": "common"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -648,7 +648,7 @@ TEST(JSONSchema_frame_draft6, relative_base_uri_with_ref) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_draft7_test.cc b/test/jsonschema/jsonschema_frame_draft7_test.cc
index 1c0b7f033..0ef347ea2 100644
--- a/test/jsonschema/jsonschema_frame_draft7_test.cc
+++ b/test/jsonschema/jsonschema_frame_draft7_test.cc
@@ -48,7 +48,7 @@ TEST(JSONSchema_frame_draft7, anonymous_with_nested_schema_resource) {
     "additionalProperties": { "$id": "https://example.com" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -95,7 +95,7 @@ TEST(JSONSchema_frame_draft7, empty_schema) {
     "$schema": "http://json-schema.org/draft-07/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -135,7 +135,7 @@ TEST(JSONSchema_frame_draft7, one_level_applicators_without_identifiers) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -192,7 +192,7 @@ TEST(JSONSchema_frame_draft7, one_level_applicators_with_identifiers) {
     "items": { "$id": "../foo", "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -256,7 +256,7 @@ TEST(JSONSchema_frame_draft7, subschema_absolute_identifier) {
      }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -317,7 +317,7 @@ TEST(JSONSchema_frame_draft7, id_override) {
     "items": { "$id": "schema" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
@@ -329,7 +329,7 @@ TEST(JSONSchema_frame_draft7, explicit_argument_id_same) {
     "$schema": "http://json-schema.org/draft-07/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-07/schema#",
@@ -375,7 +375,7 @@ TEST(JSONSchema_frame_draft7, explicit_argument_id_different) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "http://json-schema.org/draft-07/schema#",
@@ -455,7 +455,7 @@ TEST(JSONSchema_frame_draft7, ref_metaschema) {
     "$ref": "http://json-schema.org/draft-07/schema#"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -496,7 +496,7 @@ TEST(JSONSchema_frame_draft7, location_independent_identifier_anonymous) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -561,7 +561,7 @@ TEST(JSONSchema_frame_draft7, ref_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -611,7 +611,7 @@ TEST(JSONSchema_frame_draft7, relative_base_uri_without_ref) {
     "$id": "common"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -648,7 +648,7 @@ TEST(JSONSchema_frame_draft7, relative_base_uri_with_ref) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
diff --git a/test/jsonschema/jsonschema_frame_test.cc b/test/jsonschema/jsonschema_frame_test.cc
index dd7154aad..f0288bed1 100644
--- a/test/jsonschema/jsonschema_frame_test.cc
+++ b/test/jsonschema/jsonschema_frame_test.cc
@@ -26,7 +26,7 @@ TEST(JSONSchema_frame, nested_schemas_mixing_dialects) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -184,7 +184,7 @@ TEST(JSONSchema_frame, no_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -270,7 +270,7 @@ TEST(JSONSchema_frame, no_id_with_default) {
     "items": { "type": "string" }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver,
                 "https://json-schema.org/draft/2020-12/schema",
@@ -322,7 +322,7 @@ TEST(JSONSchema_frame, anchor_on_absolute_subid) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -412,7 +412,7 @@ TEST(JSONSchema_frame, uri_iterators) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -458,7 +458,7 @@ TEST(JSONSchema_frame, no_refs) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -490,7 +490,7 @@ TEST(JSONSchema_frame, refs_with_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -554,7 +554,7 @@ TEST(JSONSchema_frame, refs_with_no_id) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -595,7 +595,7 @@ TEST(JSONSchema_frame, no_dynamic_ref_on_old_drafts) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -616,7 +616,7 @@ TEST(JSONSchema_frame, remote_refs) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(document, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
 
@@ -640,7 +640,7 @@ TEST(JSONSchema_frame, no_dialect) {
     "type": "string"
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   EXPECT_THROW(frame.analyse(document, sourcemeta::core::default_schema_walker,
                              sourcemeta::core::official_resolver),
                sourcemeta::core::SchemaError);
diff --git a/test/jsonschema/jsonschema_identify_2019_09_test.cc b/test/jsonschema/jsonschema_identify_2019_09_test.cc
index cc1034cc0..f4bdb5dad 100644
--- a/test/jsonschema/jsonschema_identify_2019_09_test.cc
+++ b/test/jsonschema/jsonschema_identify_2019_09_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_2019_09, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2019-09/schema")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_2019_09, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2019-09/schema")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_2019_09, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_2020_12_test.cc b/test/jsonschema/jsonschema_identify_2020_12_test.cc
index 5f21499c9..b0586a8b1 100644
--- a/test/jsonschema/jsonschema_identify_2020_12_test.cc
+++ b/test/jsonschema/jsonschema_identify_2020_12_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_2020_12, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_2020_12, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_2020_12, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft0_test.cc b/test/jsonschema/jsonschema_identify_draft0_test.cc
index b466d7191..7c0257a65 100644
--- a/test/jsonschema/jsonschema_identify_draft0_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft0_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft0, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-00/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft0, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-00/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft0, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft1_test.cc b/test/jsonschema/jsonschema_identify_draft1_test.cc
index 0908fcedf..605cc27d2 100644
--- a/test/jsonschema/jsonschema_identify_draft1_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft1_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft1, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-01/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft1, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-01/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft1, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft2_test.cc b/test/jsonschema/jsonschema_identify_draft2_test.cc
index 8e5c3c279..80616bd17 100644
--- a/test/jsonschema/jsonschema_identify_draft2_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft2_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft2, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-02/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft2, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-02/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft2, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft3_test.cc b/test/jsonschema/jsonschema_identify_draft3_test.cc
index 08ec0fc8b..25de3e08b 100644
--- a/test/jsonschema/jsonschema_identify_draft3_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft3_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft3, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-03/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft3, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-03/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft3, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft4_test.cc b/test/jsonschema/jsonschema_identify_draft4_test.cc
index 0bdc2754d..552945dc4 100644
--- a/test/jsonschema/jsonschema_identify_draft4_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft4_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft4, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft4, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft4, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft6_test.cc b/test/jsonschema/jsonschema_identify_draft6_test.cc
index efd5d40d0..e971b0e10 100644
--- a/test/jsonschema/jsonschema_identify_draft6_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft6_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft6, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-06/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft6, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-06/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft6, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_draft7_test.cc b/test/jsonschema/jsonschema_identify_draft7_test.cc
index 98ea24445..15e04a45a 100644
--- a/test/jsonschema/jsonschema_identify_draft7_test.cc
+++ b/test/jsonschema/jsonschema_identify_draft7_test.cc
@@ -39,7 +39,7 @@ TEST(JSONSchema_identify_draft7, id_boolean_default_dialect) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-07/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -48,7 +48,7 @@ TEST(JSONSchema_identify_draft7, empty_object_default_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-07/schema#")};
   EXPECT_FALSE(id.has_value());
 }
@@ -81,7 +81,7 @@ TEST(JSONSchema_identify_draft7, default_dialect_precedence) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-04/schema#")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
diff --git a/test/jsonschema/jsonschema_identify_test.cc b/test/jsonschema/jsonschema_identify_test.cc
index 27994222d..0d6150fc3 100644
--- a/test/jsonschema/jsonschema_identify_test.cc
+++ b/test/jsonschema/jsonschema_identify_test.cc
@@ -13,7 +13,7 @@ TEST(JSONSchema_identify, boolean_no_dialect_with_default_id) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict, std::nullopt,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict, std::nullopt,
       "https://www.sourcemeta.com/foo")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://www.sourcemeta.com/foo");
@@ -23,7 +23,7 @@ TEST(JSONSchema_identify, empty_old_no_dollar_sign_id_with_default) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "http://json-schema.org/draft-00/schema#",
       "https://example.com/my-schema")};
   EXPECT_TRUE(id.has_value());
@@ -34,7 +34,7 @@ TEST(JSONSchema_identify, empty_dollar_sign_id_with_default) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Strict,
+      sourcemeta::core::SchemaIdentificationStrategy::Strict,
       "https://json-schema.org/draft/2020-12/schema",
       "https://example.com/my-schema")};
   EXPECT_TRUE(id.has_value());
@@ -45,7 +45,7 @@ TEST(JSONSchema_identify, boolean_unknown_dialect) {
   const sourcemeta::core::JSON document{true};
   EXPECT_THROW(sourcemeta::core::identify(
                    document, sourcemeta::core::official_resolver,
-                   sourcemeta::core::IdentificationStrategy::Strict,
+                   sourcemeta::core::SchemaIdentificationStrategy::Strict,
                    "https://www.sourcemeta.com/invalid-dialect"),
                sourcemeta::core::SchemaResolutionError);
 }
@@ -61,7 +61,7 @@ TEST(JSONSchema_identify, empty_object_unknown_dialect) {
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{}");
   EXPECT_THROW(sourcemeta::core::identify(
                    document, sourcemeta::core::official_resolver,
-                   sourcemeta::core::IdentificationStrategy::Strict,
+                   sourcemeta::core::SchemaIdentificationStrategy::Strict,
                    "https://www.sourcemeta.com/invalid-dialect"),
                sourcemeta::core::SchemaResolutionError);
 }
@@ -88,7 +88,7 @@ TEST(JSONSchema_identify, loose_boolean) {
   const sourcemeta::core::JSON document{true};
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_FALSE(id.has_value());
 }
 
@@ -98,7 +98,7 @@ TEST(JSONSchema_identify, loose_with_valid_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
@@ -109,7 +109,7 @@ TEST(JSONSchema_identify, loose_with_invalid_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_FALSE(id.has_value());
 }
 
@@ -119,7 +119,7 @@ TEST(JSONSchema_identify, loose_with_valid_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
@@ -130,7 +130,7 @@ TEST(JSONSchema_identify, loose_with_invalid_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_FALSE(id.has_value());
 }
 
@@ -141,7 +141,7 @@ TEST(JSONSchema_identify, loose_with_valid_dollar_id_and_invalid_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
@@ -153,7 +153,7 @@ TEST(JSONSchema_identify, loose_with_valid_id_and_invalid_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
@@ -165,7 +165,7 @@ TEST(JSONSchema_identify, loose_with_invalid_id_and_invalid_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_FALSE(id.has_value());
 }
 
@@ -176,7 +176,7 @@ TEST(JSONSchema_identify, loose_with_matching_id_and_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
@@ -188,7 +188,7 @@ TEST(JSONSchema_identify, loose_with_non_matching_id_and_dollar_id) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_FALSE(id.has_value());
 }
 
@@ -199,7 +199,7 @@ TEST(JSONSchema_identify, loose_with_resolvable_default_dialect) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose,
+      sourcemeta::core::SchemaIdentificationStrategy::Loose,
       "https://json-schema.org/draft/2020-12/schema")};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "http://example.com/my-schema");
@@ -212,7 +212,7 @@ TEST(JSONSchema_identify, loose_with_unresolvable_dialect) {
   })JSON");
   std::optional<std::string> id{sourcemeta::core::identify(
       document, sourcemeta::core::official_resolver,
-      sourcemeta::core::IdentificationStrategy::Loose)};
+      sourcemeta::core::SchemaIdentificationStrategy::Loose)};
   EXPECT_TRUE(id.has_value());
   EXPECT_EQ(id.value(), "https://example.com/my-schema");
 }
diff --git a/test/jsonschema/jsonschema_map_resolver_test.cc b/test/jsonschema/jsonschema_map_resolver_test.cc
index b33d3a742..f62045ded 100644
--- a/test/jsonschema/jsonschema_map_resolver_test.cc
+++ b/test/jsonschema/jsonschema_map_resolver_test.cc
@@ -2,14 +2,14 @@
 
 #include <sourcemeta/core/jsonschema.h>
 
-TEST(JSONSchema_MapSchemaResolver, empty_no_fallback) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, empty_no_fallback) {
+  sourcemeta::core::SchemaMapResolver resolver;
   EXPECT_FALSE(
       resolver("https://json-schema.org/draft/2020-12/schema").has_value());
 }
 
-TEST(JSONSchema_MapSchemaResolver, empty_with_fallback) {
-  sourcemeta::core::MapSchemaResolver resolver{
+TEST(JSONSchema_SchemaMapResolver, empty_with_fallback) {
+  sourcemeta::core::SchemaMapResolver resolver{
       sourcemeta::core::official_resolver};
   EXPECT_TRUE(
       resolver("https://json-schema.org/draft/2020-12/schema").has_value());
@@ -18,8 +18,8 @@ TEST(JSONSchema_MapSchemaResolver, empty_with_fallback) {
                 "https://json-schema.org/draft/2020-12/schema"));
 }
 
-TEST(JSONSchema_MapSchemaResolver, single_schema) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, single_schema) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
     "$id": "https://www.sourcemeta.com/test",
@@ -32,8 +32,8 @@ TEST(JSONSchema_MapSchemaResolver, single_schema) {
   EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), document);
 }
 
-TEST(JSONSchema_MapSchemaResolver, single_schema_with_default_dialect) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, single_schema_with_default_dialect) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
     "$id": "https://www.sourcemeta.com/test"
@@ -50,8 +50,8 @@ TEST(JSONSchema_MapSchemaResolver, single_schema_with_default_dialect) {
   EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), expected);
 }
 
-TEST(JSONSchema_MapSchemaResolver, single_schema_anonymous_with_default) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, single_schema_anonymous_with_default) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
     "$schema": "https://json-schema.org/draft/2020-12/schema"
@@ -68,8 +68,8 @@ TEST(JSONSchema_MapSchemaResolver, single_schema_anonymous_with_default) {
   EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), expected);
 }
 
-TEST(JSONSchema_MapSchemaResolver, single_schema_idempotent) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, single_schema_idempotent) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
     "$id": "https://www.sourcemeta.com/test",
@@ -84,8 +84,8 @@ TEST(JSONSchema_MapSchemaResolver, single_schema_idempotent) {
   EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), document);
 }
 
-TEST(JSONSchema_MapSchemaResolver, duplicate_ids) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, duplicate_ids) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document_1 =
       sourcemeta::core::parse_json(R"JSON({
@@ -104,8 +104,8 @@ TEST(JSONSchema_MapSchemaResolver, duplicate_ids) {
   EXPECT_THROW(resolver.add(document_2), sourcemeta::core::SchemaError);
 }
 
-TEST(JSONSchema_MapSchemaResolver, embedded_resource) {
-  sourcemeta::core::MapSchemaResolver resolver;
+TEST(JSONSchema_SchemaMapResolver, embedded_resource) {
+  sourcemeta::core::SchemaMapResolver resolver;
 
   const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
     "$id": "https://www.sourcemeta.com/test",
diff --git a/test/jsonschema/jsonschema_test_utils.h b/test/jsonschema/jsonschema_test_utils.h
index 645af0020..b3ccb0986 100644
--- a/test/jsonschema/jsonschema_test_utils.h
+++ b/test/jsonschema/jsonschema_test_utils.h
@@ -42,8 +42,8 @@
                             expected_dialect, expected_base_dialect,           \
                             expected_base, expected_relative_pointer,          \
                             expected_destination_of_size)                      \
-  EXPECT_FRAME(frame, sourcemeta::core::ReferenceType::Static, reference,      \
-               root_id, expected_pointer, expected_dialect,                    \
+  EXPECT_FRAME(frame, sourcemeta::core::SchemaReferenceType::Static,           \
+               reference, root_id, expected_pointer, expected_dialect,         \
                expected_base_dialect, expected_base,                           \
                expected_relative_pointer, expected_destination_of_size)
 
@@ -54,11 +54,12 @@
   EXPECT_FRAME_STATIC(frame, reference, root_id, expected_pointer,             \
                       expected_dialect, expected_base_dialect, expected_base,  \
                       expected_relative_pointer, expected_destination_of_size) \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Resource);
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Resource);
 
 #define EXPECT_FRAME_STATIC_POINTER(                                           \
     frame, reference, root_id, expected_pointer, expected_dialect,             \
@@ -67,11 +68,12 @@
   EXPECT_FRAME_STATIC(frame, reference, root_id, expected_pointer,             \
                       expected_dialect, expected_base_dialect, expected_base,  \
                       expected_relative_pointer, expected_destination_of_size) \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Pointer);
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Pointer);
 
 #define EXPECT_FRAME_STATIC_SUBSCHEMA(                                         \
     frame, reference, root_id, expected_pointer, expected_dialect,             \
@@ -80,11 +82,12 @@
   EXPECT_FRAME_STATIC(frame, reference, root_id, expected_pointer,             \
                       expected_dialect, expected_base_dialect, expected_base,  \
                       expected_relative_pointer, expected_destination_of_size) \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Subschema);
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Subschema);
 
 #define EXPECT_FRAME_STATIC_ANCHOR(                                            \
     frame, reference, root_id, expected_pointer, expected_dialect,             \
@@ -93,11 +96,12 @@
   EXPECT_FRAME_STATIC(frame, reference, root_id, expected_pointer,             \
                       expected_dialect, expected_base_dialect, expected_base,  \
                       expected_relative_pointer, expected_destination_of_size) \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Anchor);
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Anchor);
 
 #define EXPECT_FRAME_DYNAMIC_ANCHOR(                                           \
     frame, reference, root_id, expected_pointer, expected_dialect,             \
@@ -107,18 +111,19 @@
                        expected_dialect, expected_base_dialect, expected_base, \
                        expected_relative_pointer,                              \
                        expected_destination_of_size)                           \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Dynamic, (reference)})   \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Anchor);
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Dynamic, (reference)})   \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Anchor);
 
 #define EXPECT_FRAME_DYNAMIC(frame, reference, root_id, expected_pointer,      \
                              expected_dialect, expected_base_dialect,          \
                              expected_base, expected_relative_pointer,         \
                              expected_destination_of_size)                     \
-  EXPECT_FRAME(frame, sourcemeta::core::ReferenceType::Dynamic, reference,     \
-               root_id, expected_pointer, expected_dialect,                    \
+  EXPECT_FRAME(frame, sourcemeta::core::SchemaReferenceType::Dynamic,          \
+               reference, root_id, expected_pointer, expected_dialect,         \
                expected_base_dialect, expected_base,                           \
                expected_relative_pointer, expected_destination_of_size)
 
@@ -146,75 +151,80 @@
 #define EXPECT_ANONYMOUS_FRAME_STATIC(frame, reference, expected_pointer,      \
                                       expected_dialect, expected_base_dialect, \
                                       expected_destination_of_size)            \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Static,     \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Static, reference,         \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)
 
 #define EXPECT_ANONYMOUS_FRAME_STATIC_RESOURCE(                                \
     frame, reference, expected_pointer, expected_dialect,                      \
     expected_base_dialect, expected_destination_of_size)                       \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Static,     \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)                       \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Resource);
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Static, reference,         \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)                                            \
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Resource);
 
 #define EXPECT_ANONYMOUS_FRAME_STATIC_POINTER(                                 \
     frame, reference, expected_pointer, expected_dialect,                      \
     expected_base_dialect, expected_destination_of_size)                       \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Static,     \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)                       \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Pointer);
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Static, reference,         \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)                                            \
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Pointer);
 
 #define EXPECT_ANONYMOUS_FRAME_STATIC_SUBSCHEMA(                               \
     frame, reference, expected_pointer, expected_dialect,                      \
     expected_base_dialect, expected_destination_of_size)                       \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Static,     \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)                       \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Subschema);
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Static, reference,         \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)                                            \
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Subschema);
 
 #define EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(                                  \
     frame, reference, expected_pointer, expected_dialect,                      \
     expected_base_dialect, expected_destination_of_size)                       \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Static,     \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)                       \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Static, (reference)})    \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Anchor);
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Static, reference,         \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)                                            \
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Static, (reference)})    \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Anchor);
 
 #define EXPECT_ANONYMOUS_FRAME_DYNAMIC_ANCHOR(                                 \
     frame, reference, expected_pointer, expected_dialect,                      \
     expected_base_dialect, expected_destination_of_size)                       \
-  __EXPECT_ANONYMOUS_FRAME(frame, sourcemeta::core::ReferenceType::Dynamic,    \
-                           reference, expected_pointer, expected_dialect,      \
-                           expected_base_dialect,                              \
-                           expected_destination_of_size)                       \
-  EXPECT_EQ((frame)                                                            \
-                .locations()                                                   \
-                .at({sourcemeta::core::ReferenceType::Dynamic, (reference)})   \
-                .type,                                                         \
-            sourcemeta::core::Frame::LocationType::Anchor);
+  __EXPECT_ANONYMOUS_FRAME(                                                    \
+      frame, sourcemeta::core::SchemaReferenceType::Dynamic, reference,        \
+      expected_pointer, expected_dialect, expected_base_dialect,               \
+      expected_destination_of_size)                                            \
+  EXPECT_EQ(                                                                   \
+      (frame)                                                                  \
+          .locations()                                                         \
+          .at({sourcemeta::core::SchemaReferenceType::Dynamic, (reference)})   \
+          .type,                                                               \
+      sourcemeta::core::SchemaFrame::LocationType::Anchor);
 
 #define EXPECT_REFERENCE(frame, expected_type, expected_pointer, expected_uri, \
                          expected_base, expected_fragment)                     \
@@ -238,32 +248,32 @@
 
 #define EXPECT_STATIC_REFERENCE(frame, expected_pointer, expected_uri,         \
                                 expected_base, expected_fragment)              \
-  EXPECT_REFERENCE(frame, sourcemeta::core::ReferenceType::Static,             \
+  EXPECT_REFERENCE(frame, sourcemeta::core::SchemaReferenceType::Static,       \
                    expected_pointer, expected_uri, expected_base,              \
                    expected_fragment)
 
 #define EXPECT_DYNAMIC_REFERENCE(frame, expected_pointer, expected_uri,        \
                                  expected_base, expected_fragment)             \
-  EXPECT_REFERENCE(frame, sourcemeta::core::ReferenceType::Dynamic,            \
+  EXPECT_REFERENCE(frame, sourcemeta::core::SchemaReferenceType::Dynamic,      \
                    expected_pointer, expected_uri, expected_base,              \
                    expected_fragment)
 
 #define EXPECT_FRAME_DESTINATION_OF(frame, expected_type, expected_uri,        \
                                     expected_index, expected_origin)           \
-  EXPECT_EQ(                                                                   \
-      frame.locations()                                                        \
-          .at({sourcemeta::core::ReferenceType::expected_type, expected_uri})  \
-          .destination_of.at(expected_index)                                   \
-          .get()                                                               \
-          .first,                                                              \
-      sourcemeta::core::ReferenceType::Static);                                \
-  EXPECT_EQ(                                                                   \
-      frame.locations()                                                        \
-          .at({sourcemeta::core::ReferenceType::expected_type, expected_uri})  \
-          .destination_of.at(expected_index)                                   \
-          .get()                                                               \
-          .second,                                                             \
-      TO_POINTER(expected_origin));
+  EXPECT_EQ(frame.locations()                                                  \
+                .at({sourcemeta::core::SchemaReferenceType::expected_type,     \
+                     expected_uri})                                            \
+                .destination_of.at(expected_index)                             \
+                .get()                                                         \
+                .first,                                                        \
+            sourcemeta::core::SchemaReferenceType::Static);                    \
+  EXPECT_EQ(frame.locations()                                                  \
+                .at({sourcemeta::core::SchemaReferenceType::expected_type,     \
+                     expected_uri})                                            \
+                .destination_of.at(expected_index)                             \
+                .get()                                                         \
+                .second,                                                       \
+            TO_POINTER(expected_origin));
 
 #define EXPECT_UNEVALUATED_STATIC(keywords, expected_pointer,                  \
                                   expected_dependencies_size)                  \
diff --git a/test/jsonschema/jsonschema_unevaluated_2019_09_test.cc b/test/jsonschema/jsonschema_unevaluated_2019_09_test.cc
index 8ea27d199..20026c240 100644
--- a/test/jsonschema/jsonschema_unevaluated_2019_09_test.cc
+++ b/test/jsonschema/jsonschema_unevaluated_2019_09_test.cc
@@ -15,7 +15,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedProperties_1) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -47,7 +47,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedProperties_2) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -95,7 +95,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedProperties_3) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -134,7 +134,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedProperties_4) {
     ]
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -165,7 +165,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedItems_1) {
     "unevaluatedItems": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -200,7 +200,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedItems_2) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -225,7 +225,7 @@ TEST(JSONSchema_unevaluated_2019_09, unevaluatedItems_3) {
     "unevaluatedItems": {"type": "string"}
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
diff --git a/test/jsonschema/jsonschema_unevaluated_2020_12_test.cc b/test/jsonschema/jsonschema_unevaluated_2020_12_test.cc
index a8932d216..e8978395f 100644
--- a/test/jsonschema/jsonschema_unevaluated_2020_12_test.cc
+++ b/test/jsonschema/jsonschema_unevaluated_2020_12_test.cc
@@ -15,7 +15,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_1) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -47,7 +47,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_2) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -82,7 +82,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_3) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -120,7 +120,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_4) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -152,7 +152,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_5) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -180,7 +180,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_6) {
     "unevaluatedProperties": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -219,7 +219,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_7) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -260,7 +260,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedProperties_8) {
     }
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -286,7 +286,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedItems_1) {
     "unevaluatedItems": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
@@ -314,7 +314,7 @@ TEST(JSONSchema_unevaluated_2020_12, unevaluatedItems_2) {
     "unevaluatedItems": false
   })JSON");
 
-  sourcemeta::core::Frame frame;
+  sourcemeta::core::SchemaFrame frame;
   frame.analyse(schema, sourcemeta::core::default_schema_walker,
                 sourcemeta::core::official_resolver);
   const auto result{sourcemeta::core::unevaluated(
diff --git a/test/jsonschema/jsonschema_walker_test.cc b/test/jsonschema/jsonschema_walker_test.cc
index 199664795..1da099b7b 100644
--- a/test/jsonschema/jsonschema_walker_test.cc
+++ b/test/jsonschema/jsonschema_walker_test.cc
@@ -37,31 +37,31 @@ static auto test_walker(std::string_view keyword,
   if (vocabularies.find("https://sourcemeta.com/vocab/test-1") !=
       vocabularies.end()) {
     if (keyword == "schema") {
-      return {sourcemeta::core::KeywordType::ApplicatorValue,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorValue,
               "https://sourcemeta.com/vocab/test-1",
               {}};
     }
 
     if (keyword == "schemas") {
-      return {sourcemeta::core::KeywordType::ApplicatorElements,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorElements,
               "https://sourcemeta.com/vocab/test-1",
               {}};
     }
 
     if (keyword == "schemaMap") {
-      return {sourcemeta::core::KeywordType::ApplicatorMembers,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorMembers,
               "https://sourcemeta.com/vocab/test-1",
               {}};
     }
 
     if (keyword == "schemaOrSchemas") {
-      return {sourcemeta::core::KeywordType::ApplicatorValueOrElements,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorValueOrElements,
               "https://sourcemeta.com/vocab/test-1",
               {}};
     }
 
     if (keyword == "schemasOrMap") {
-      return {sourcemeta::core::KeywordType::ApplicatorElementsOrMembers,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorElementsOrMembers,
               "https://sourcemeta.com/vocab/test-1",
               {}};
     }
@@ -70,13 +70,13 @@ static auto test_walker(std::string_view keyword,
   if (vocabularies.find("https://sourcemeta.com/vocab/test-2") !=
       vocabularies.end()) {
     if (keyword == "custom") {
-      return {sourcemeta::core::KeywordType::ApplicatorValue,
+      return {sourcemeta::core::SchemaKeywordType::ApplicatorValue,
               "https://sourcemeta.com/vocab/test-2",
               {}};
     }
   }
 
-  return {sourcemeta::core::KeywordType::Unknown, std::nullopt, {}};
+  return {sourcemeta::core::SchemaKeywordType::Unknown, std::nullopt, {}};
 }
 
 TEST(JSONSchema_walker, true) {
diff --git a/test/jsonschema/referencingsuite.cc b/test/jsonschema/referencingsuite.cc
index 7f48f052c..493b57faa 100644
--- a/test/jsonschema/referencingsuite.cc
+++ b/test/jsonschema/referencingsuite.cc
@@ -49,7 +49,7 @@ class ReferencingTest : public testing::Test {
     std::map<std::string, std::pair<sourcemeta::core::JSON, std::string>>
         new_entries;
     for (const auto &[uri, schema] : this->registry) {
-      sourcemeta::core::Frame frame;
+      sourcemeta::core::SchemaFrame frame;
       frame.analyse(schema.first, sourcemeta::core::default_schema_walker,
                     sourcemeta::core::official_resolver, this->dialect, uri);
       for (const auto &[key, entry] : frame.locations()) {