Remove '@' from RepositoryName constructors

This CL changes it so that RepositoryName#create no longer takes an argument that starts with '@' (that is, it now always takes the "stripped" name).

Also #createWithValidStrippedName is renamed to #createUnvalidated.

Notably, it does *not* try to change the caching logic, and still stores a '@'-prefixed string. This is in order to minimize change in behavior. Fixing those will come later.

PiperOrigin-RevId: 441759032
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionValue.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionValue.java
index 9a1a923..23b0005 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelModuleResolutionValue.java
@@ -99,8 +99,8 @@
         String canonicalRepoName =
             getExtensionUniqueNames().get(extensionId) + "." + entry.getValue();
         mapping.put(
-            RepositoryName.createFromValidStrippedName(entry.getKey()),
-            RepositoryName.createFromValidStrippedName(canonicalRepoName));
+            RepositoryName.createUnvalidated(entry.getKey()),
+            RepositoryName.createUnvalidated(canonicalRepoName));
       }
     }
     return getDepGraph()
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java
index 70670bd..13ae614 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Module.java
@@ -106,15 +106,15 @@
     // If this is the root module, this perfectly falls into @<module name> => @
     if (!getName().isEmpty()) {
       mapping.put(
-          RepositoryName.createFromValidStrippedName(getName()),
-          RepositoryName.createFromValidStrippedName(getCanonicalRepoName()));
+          RepositoryName.createUnvalidated(getName()),
+          RepositoryName.createUnvalidated(getCanonicalRepoName()));
     }
     for (Map.Entry<String, ModuleKey> dep : getDeps().entrySet()) {
       // Special note: if `dep` is actually the root module, its ModuleKey would be ROOT whose
       // canonicalRepoName is the empty string. This perfectly maps to the main repo ("@").
       mapping.put(
-          RepositoryName.createFromValidStrippedName(dep.getKey()),
-          RepositoryName.createFromValidStrippedName(dep.getValue().getCanonicalRepoName()));
+          RepositoryName.createUnvalidated(dep.getKey()),
+          RepositoryName.createUnvalidated(dep.getValue().getCanonicalRepoName()));
     }
     return RepositoryMapping.create(mapping.buildOrThrow(), getCanonicalRepoName());
   }
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java
index ae96ade..b16c20a 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunction.java
@@ -216,7 +216,7 @@
           (RepositoryDirectoryValue)
               env.getValue(
                   RepositoryDirectoryValue.key(
-                      RepositoryName.createFromValidStrippedName(canonicalRepoName)));
+                      RepositoryName.createUnvalidated(canonicalRepoName)));
       if (repoDir == null) {
         return null;
       }
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/StarlarkBazelModule.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/StarlarkBazelModule.java
index 43b65db..bfb902d 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/StarlarkBazelModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/StarlarkBazelModule.java
@@ -95,8 +95,7 @@
   static Label createModuleRootLabel(String canonicalRepoName) {
     return Label.createUnvalidated(
         PackageIdentifier.create(
-            RepositoryName.createFromValidStrippedName(canonicalRepoName),
-            PathFragment.EMPTY_FRAGMENT),
+            RepositoryName.createUnvalidated(canonicalRepoName), PathFragment.EMPTY_FRAGMENT),
         "unused_dummy_target_name");
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java b/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
index 2f4ed59..6818260 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
@@ -196,7 +196,7 @@
           // TODO(aehlig): avoid the detour of serializing and then parsing the repository name
           try {
             repositoriesToFetch.add(
-                RepositoryDirectoryValue.key(RepositoryName.create("@" + rule.getName())));
+                RepositoryDirectoryValue.key(RepositoryName.create(rule.getName())));
           } catch (LabelSyntaxException e) {
             String errorMessage =
                 String.format(
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/CacheHitReportingModule.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/CacheHitReportingModule.java
index 7d33c99..90d551c 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/CacheHitReportingModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/CacheHitReportingModule.java
@@ -15,7 +15,6 @@
 
 import com.google.common.eventbus.Subscribe;
 import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCacheHitEvent;
-import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.repository.RepositoryFailedEvent;
@@ -48,7 +47,7 @@
 
   @Subscribe
   public synchronized void cacheHit(RepositoryCacheHitEvent event) {
-    String repo = event.getRepo();
+    String repo = event.getRepo().getName();
     if (cacheHitsByRepo.get(repo) == null) {
       cacheHitsByRepo.put(repo, new HashSet<Pair<String, URL>>());
     }
@@ -57,7 +56,7 @@
 
   @Subscribe
   public void failed(RepositoryFailedEvent event) {
-    String repo = RepositoryName.stripName(event.getRepo());
+    String repo = event.getRepo().getName();
     Set<Pair<String, URL>> cacheHits = cacheHitsByRepo.get(repo);
     if (cacheHits != null && !cacheHits.isEmpty()) {
       StringBuilder info = new StringBuilder();
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
index d7b38eb..0de4d56 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java
@@ -272,7 +272,7 @@
             "Repository override directory must be an absolute path", input);
       }
       try {
-        return RepositoryOverride.create(RepositoryName.create("@" + pieces[0]), path);
+        return RepositoryOverride.create(RepositoryName.create(pieces[0]), path);
       } catch (LabelSyntaxException e) {
         throw new OptionsParsingException("Invalid repository name given to override", input);
       }
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/BUILD
index df60bcc..bbc1707 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/BUILD
@@ -24,6 +24,7 @@
     name = "events",
     srcs = ["RepositoryCacheHitEvent.java"],
     deps = [
+        "//src/main/java/com/google/devtools/build/lib/cmdline:cmdline-primitives",
         "//src/main/java/com/google/devtools/build/lib/events",
     ],
 )
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCacheHitEvent.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCacheHitEvent.java
index 009b294..25dca96 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCacheHitEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/cache/RepositoryCacheHitEvent.java
@@ -14,22 +14,23 @@
 
 package com.google.devtools.build.lib.bazel.repository.cache;
 
+import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.events.ExtendedEventHandler.ProgressLike;
 import java.net.URL;
 
 /** Event reporting about cache hits for download requests. */
 public class RepositoryCacheHitEvent implements ProgressLike {
-  private final String repo;
+  private final RepositoryName repo;
   private final String hash;
   private final URL url;
 
-  public RepositoryCacheHitEvent(String repo, String hash, URL url) {
+  public RepositoryCacheHitEvent(RepositoryName repo, String hash, URL url) {
     this.repo = repo;
     this.hash = hash;
     this.url = url;
   }
 
-  public String getRepo() {
+  public RepositoryName getRepo() {
     return repo;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/BUILD
index 8b2a5db..ae96486 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/BUILD
@@ -18,6 +18,7 @@
         "//src/main/java/com/google/devtools/build/lib/bazel/repository/cache:events",
         "//src/main/java/com/google/devtools/build/lib/buildeventstream",
         "//src/main/java/com/google/devtools/build/lib/clock",
+        "//src/main/java/com/google/devtools/build/lib/cmdline:cmdline-primitives",
         "//src/main/java/com/google/devtools/build/lib/concurrent",
         "//src/main/java/com/google/devtools/build/lib/events",
         "//src/main/java/com/google/devtools/build/lib/util",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/DownloadManager.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/DownloadManager.java
index 5a694a6..a2343dc 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/DownloadManager.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/downloader/DownloadManager.java
@@ -25,6 +25,7 @@
 import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache;
 import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache.KeyType;
 import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCacheHitEvent;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.ExtendedEventHandler;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -171,7 +172,9 @@
               repositoryCache.get(cacheKey, destination, cacheKeyType, canonicalId);
           if (cachedDestination != null) {
             // Cache hit!
-            eventHandler.post(new RepositoryCacheHitEvent(repo, cacheKey, mainUrl));
+            eventHandler.post(
+                new RepositoryCacheHitEvent(
+                    RepositoryName.createUnvalidated(repo), cacheKey, mainUrl));
             return cachedDestination;
           }
         } catch (IOException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
index 5691264..9f218fe 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -89,9 +89,7 @@
     Parts parts = Parts.parse(raw);
     parts.checkPkgIsAbsolute();
     RepositoryName repoName =
-        parts.repo == null
-            ? RepositoryName.MAIN
-            : RepositoryName.createFromValidStrippedName(parts.repo);
+        parts.repo == null ? RepositoryName.MAIN : RepositoryName.createUnvalidated(parts.repo);
     return createUnvalidated(
         PackageIdentifier.create(repoName, PathFragment.create(parts.pkg)), parts.target);
   }
@@ -105,7 +103,7 @@
       return ABSOLUTE_PACKAGE_NAMES.contains(parts.pkg) ? RepositoryName.MAIN : currentRepo;
     }
     // TODO(b/200024947): Make repo mapping take a string and return a RepositoryName.
-    return repoMapping.get(RepositoryName.createFromValidStrippedName(parts.repo));
+    return repoMapping.get(RepositoryName.createUnvalidated(parts.repo));
   }
 
   // TODO(b/200024947): Make this public.
@@ -277,9 +275,7 @@
     }
     // TODO(b/200024947): This method will eventually need to take a repo mapping too.
     RepositoryName repoName =
-        parts.repo == null
-            ? RepositoryName.MAIN
-            : RepositoryName.createFromValidStrippedName(parts.repo);
+        parts.repo == null ? RepositoryName.MAIN : RepositoryName.createUnvalidated(parts.repo);
     return create(PackageIdentifier.create(repoName, pathFragment), parts.target);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/LabelParser.java b/src/main/java/com/google/devtools/build/lib/cmdline/LabelParser.java
index 75afd2f..19cc182 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/LabelParser.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/LabelParser.java
@@ -117,14 +117,9 @@
       return validateAndCreate(repo, pkgIsAbsolute, pkg, target, rawLabel);
     }
 
-    @Nullable
     private static void validateRepoName(@Nullable String repo) throws LabelSyntaxException {
-      if (repo == null) {
-        return;
-      }
-      String error = RepositoryName.validate('@' + repo);
-      if (error != null) {
-        throw syntaxErrorf("invalid repository name '@%s': %s", repo, error);
+      if (repo != null) {
+        RepositoryName.validate('@' + repo);
       }
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
index 6556078..01c7350 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
@@ -83,7 +83,7 @@
     if (tofind.startsWith(prefix)) {
       // Using the path prefix can be either "external" or "..", depending on whether the sibling
       // repository layout is used.
-      RepositoryName repository = RepositoryName.createFromValidStrippedName(tofind.getSegment(1));
+      RepositoryName repository = RepositoryName.createUnvalidated(tofind.getSegment(1));
       return PackageIdentifier.create(repository, tofind.subFragment(2));
     } else {
       return PackageIdentifier.createInMainRepo(tofind);
@@ -116,9 +116,7 @@
     }
     LabelParser.Parts parts = LabelParser.Parts.parse(input + ":dummy_target");
     RepositoryName repoName =
-        parts.repo == null
-            ? RepositoryName.MAIN
-            : RepositoryName.createFromValidStrippedName(parts.repo);
+        parts.repo == null ? RepositoryName.MAIN : RepositoryName.createUnvalidated(parts.repo);
     return create(repoName, PathFragment.create(parts.pkg));
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
index b608b3f..ce1ce56 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
@@ -48,31 +48,23 @@
           .weakValues()
           .build(
               name -> {
-                String errorMessage = validate(name);
-                if (errorMessage != null) {
-                  errorMessage =
-                      "invalid repository name '"
-                          + StringUtilities.sanitizeControlChars(name)
-                          + "': "
-                          + errorMessage;
-                  throw new LabelSyntaxException(errorMessage);
-                }
+                validate(name);
                 return new RepositoryName(StringCanonicalizer.intern(name));
               });
 
   /**
    * Makes sure that name is a valid repository name and creates a new RepositoryName using it. The
-   * given string must begin with a '@'.
+   * given string must not begin with a '@'.
    *
    * @throws LabelSyntaxException if the name is invalid
    */
   public static RepositoryName create(String name) throws LabelSyntaxException {
-    // TODO(b/200024947): Get rid of the '@'.
-    if (name.isEmpty() || name.equals("@")) {
+    if (name.isEmpty()) {
       return MAIN;
     }
+    // TODO(b/200024947): Get rid of the '@' in the #name field.
     try {
-      return repositoryNameCache.get(name);
+      return repositoryNameCache.get('@' + name);
     } catch (CompletionException e) {
       Throwables.propagateIfPossible(e.getCause(), LabelSyntaxException.class);
       throw e;
@@ -80,10 +72,10 @@
   }
 
   /**
-   * Creates a RepositoryName from a known-valid string (not @-prefixed). Generally this is a
-   * directory that has been created via getSourceRoot() or getPathUnderExecRoot().
+   * Creates a RepositoryName from a known-valid string. The given string must not begin with a '@'.
    */
-  public static RepositoryName createFromValidStrippedName(String name) {
+  public static RepositoryName createUnvalidated(String name) {
+    Preconditions.checkArgument(!name.startsWith("@"), "Do not prefix @ to repo names!");
     if (name.isEmpty()) {
       // NOTE(wyv): Without this `if` clause, a lot of Google-internal integration tests would start
       //   failing. This suggests to me that something is comparing RepositoryName objects using
@@ -116,7 +108,7 @@
     }
 
     try {
-      RepositoryName repoName = RepositoryName.create("@" + path.getSegment(1));
+      RepositoryName repoName = RepositoryName.create(path.getSegment(1));
       PathFragment subPath = path.subFragment(2);
       return Pair.of(repoName, subPath);
     } catch (LabelSyntaxException e) {
@@ -143,35 +135,31 @@
     this(name, null);
   }
 
-  /** Performs validity checking. Returns null on success, an error message otherwise. */
-  static String validate(String name) {
+  /**
+   * Performs validity checking, throwing an exception if the given name is invalid. The exception
+   * message is sanitized.
+   */
+  static void validate(String name) throws LabelSyntaxException {
     if (name.isEmpty() || name.equals("@")) {
-      return null;
+      return;
     }
 
     // Some special cases for more user-friendly error messages.
-    if (!name.startsWith("@")) {
-      return "workspace names must start with '@'";
-    }
-    if (name.equals("@.")) {
-      return "workspace names are not allowed to be '@.'";
-    }
-    if (name.equals("@..")) {
-      return "workspace names are not allowed to be '@..'";
+    if (name.equals("@.") || name.equals("@..")) {
+      throw LabelParser.syntaxErrorf(
+          "invalid repository name '%s': repo names are not allowed to be '%s'", name, name);
     }
 
     if (!VALID_REPO_NAME.matcher(name).matches()) {
-      return "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'";
+      throw LabelParser.syntaxErrorf(
+          "invalid repository name '%s': repo names may contain only A-Z, a-z, 0-9, '-', '_' and"
+              + " '.'",
+          StringUtilities.sanitizeControlChars(name));
     }
-
-    return null;
   }
 
   /** Returns the repository name without the leading "{@literal @}". */
   public String getName() {
-    if (name.isEmpty()) {
-      return name;
-    }
     return name.substring(1);
   }
 
@@ -194,34 +182,24 @@
     return ownerRepoIfNotVisible;
   }
 
-  /**
-   * Returns the repository name without the leading "{@literal @}". For the default repository,
-   * returns "".
-   */
-  public static String stripName(String repoName) {
-    return repoName.startsWith("@") ? repoName.substring(1) : repoName;
-  }
-
   /** Returns if this is the main repository, that is, {@link #getName} is empty. */
   public boolean isMain() {
     return name.equals("@");
   }
 
-  /**
-   * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
-   */
+  /** Returns the repository name, with leading "{@literal @}". */
   // TODO(bazel-team): Use this over toString()- easier to track its usage.
   public String getNameWithAt() {
     return name;
   }
 
   /**
-   * Returns the repository name, except that the main repo is conflated with the default repo
-   * ({@code "@"} becomes the empty string).
+   * Returns the repository name with leading '@' except for the main repo, which is just the empty
+   * string.
    */
   // TODO(bazel-team): Consider renaming to "getDefaultForm".
   public String getCanonicalForm() {
-    return isMain() ? "" : name;
+    return isMain() ? "" : getNameWithAt();
   }
 
   /**
@@ -252,12 +230,10 @@
         : PathFragment.create("..").getRelative(getName());
   }
 
-  /**
-   * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
-   */
+  /** Returns the repository name, with leading "{@literal @}". */
   @Override
   public String toString() {
-    return name;
+    return getNameWithAt();
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
index bbcb99a..e02aeee 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
@@ -912,7 +912,7 @@
               "Couldn't find package in target " + pattern, TargetPatterns.Code.PACKAGE_NOT_FOUND);
         }
         try {
-          repository = repoMapping.get(RepositoryName.create(pattern.substring(0, pkgStart)));
+          repository = repoMapping.get(RepositoryName.create(pattern.substring(1, pkgStart)));
         } catch (LabelSyntaxException e) {
           throw new TargetParsingException(e.getMessage(), TargetPatterns.Code.LABEL_SYNTAX_ERROR);
         }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactoryHelper.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactoryHelper.java
index 6e27b10..7f0d951 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactoryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactoryHelper.java
@@ -104,8 +104,8 @@
       // Create repository names with validation, LabelSyntaxException is thrown is the name
       // is not valid.
       builder.addRepositoryMappingEntry(
-          RepositoryName.create("@" + externalRepoName),
-          RepositoryName.create("@" + builder.getPackageWorkspaceName()),
+          RepositoryName.create(externalRepoName),
+          RepositoryName.create(builder.getPackageWorkspaceName()),
           RepositoryName.MAIN);
     }
   }
@@ -124,10 +124,20 @@
       for (Map.Entry<String, String> e :
           Dict.cast(repoMapping, String.class, String.class, "repo_mapping").entrySet()) {
         // Create repository names with validation; may throw LabelSyntaxException.
+        // For legacy reasons, the repository names given to the repo_mapping attribute need to be
+        // prefixed with an @.
+        if (!e.getKey().startsWith("@")) {
+          throw new LabelSyntaxException(
+              "invalid repository name '" + e.getKey() + "': repo names must start with '@'");
+        }
+        if (!e.getValue().startsWith("@")) {
+          throw new LabelSyntaxException(
+              "invalid repository name '" + e.getValue() + "': repo names must start with '@'");
+        }
         builder.addRepositoryMappingEntry(
-            RepositoryName.create("@" + externalRepoName),
-            RepositoryName.create(e.getKey()),
-            RepositoryName.create(e.getValue()));
+            RepositoryName.create(externalRepoName),
+            RepositoryName.create(e.getKey().substring(1)),
+            RepositoryName.create(e.getValue().substring(1)));
       }
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceGlobals.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceGlobals.java
index a531eb2..f29e7ef 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceGlobals.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceGlobals.java
@@ -104,7 +104,7 @@
     // Add entry in repository map from "@name" --> "@" to avoid issue where bazel
     // treats references to @name as a separate external repo
     builder.addRepositoryMappingEntry(
-        RepositoryName.MAIN, RepositoryName.createFromValidStrippedName(name), RepositoryName.MAIN);
+        RepositoryName.MAIN, RepositoryName.createUnvalidated(name), RepositoryName.MAIN);
     parseManagedDirectories(
         Dict.cast(managedDirectories, String.class, Object.class, "managed_directories"));
   }
@@ -177,7 +177,7 @@
           "Cannot parse repository name '%s'. Repository name should start with '@'.", key);
     }
     try {
-      return RepositoryName.create(key);
+      return RepositoryName.create(key.substring(1));
     } catch (LabelSyntaxException e) {
       throw Starlark.errorf("%s", e);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/repository/RepositoryFailedEvent.java b/src/main/java/com/google/devtools/build/lib/repository/RepositoryFailedEvent.java
index a6e84f6..5db49f0 100644
--- a/src/main/java/com/google/devtools/build/lib/repository/RepositoryFailedEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/repository/RepositoryFailedEvent.java
@@ -24,6 +24,7 @@
 import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.events.ExtendedEventHandler.ProgressLike;
 import java.util.Collection;
 
@@ -32,24 +33,21 @@
  * the case, if fetching that repository failed.
  */
 public class RepositoryFailedEvent implements ProgressLike, BuildEvent {
-  private final String repo;
+  private final RepositoryName repo;
   private final String message;
 
-  public RepositoryFailedEvent(String repo, String message) {
+  public RepositoryFailedEvent(RepositoryName repo, String message) {
     this.repo = repo;
     this.message = message;
   }
 
-  public String getRepo() {
+  public RepositoryName getRepo() {
     return repo;
   }
 
   @Override
   public BuildEventId getEventId() {
-    String strippedRepoName = repo;
-    if (strippedRepoName.startsWith("@")) {
-      strippedRepoName = strippedRepoName.substring(1);
-    }
+    String strippedRepoName = repo.getName();
     try {
       Label label = Label.create(EXTERNAL_PACKAGE_IDENTIFIER, strippedRepoName);
       return BuildEventIdUtil.unconfiguredLabelId(label);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
index 361bd27..87e0d4a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
@@ -216,7 +216,7 @@
   }
 
   private static RepositoryName getToolsRepository(RuleContext ruleContext) {
-    return RepositoryName.createFromValidStrippedName(
+    return RepositoryName.createUnvalidated(
         ruleContext.attributes().get(ConfigSettingRule.TOOLS_REPOSITORY_ATTRIBUTE, Type.STRING));
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
index f87e2b1..21bd2ec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
@@ -419,7 +419,8 @@
     } catch (RepositoryFunctionException e) {
       // Upon an exceptional exit, the fetching of that repository is over as well.
       env.getListener().post(new RepositoryFetching(repositoryName, true));
-      env.getListener().post(new RepositoryFailedEvent(repositoryName, e.getMessage()));
+      env.getListener()
+          .post(new RepositoryFailedEvent((RepositoryName) skyKey.argument(), e.getMessage()));
       env.getListener()
           .handle(
               Event.error(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index e8d6924..10a2f67 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -523,8 +523,7 @@
       return;
     }
     String repositoryName = repositoryPath.getSegment(0);
-    env.getValue(
-        RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName(repositoryName)));
+    env.getValue(RepositoryDirectoryValue.key(RepositoryName.createUnvalidated(repositoryName)));
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationFunction.java
index fde86b8..796da77 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationFunction.java
@@ -114,7 +114,7 @@
     try {
       return BuildConfigurationValue.create(
           targetOptions,
-          RepositoryName.createFromValidStrippedName(workspaceNameValue.getName()),
+          RepositoryName.createUnvalidated(workspaceNameValue.getName()),
           starlarkSemantics.getBool(BuildLanguageOptions.EXPERIMENTAL_SIBLING_REPOSITORY_LAYOUT),
           transitionDirectoryNameFragment,
           // Arguments below this are server-global.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
index 49aade1..79fc1ff 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
@@ -190,7 +190,7 @@
           String path = (String) rule.getAttr("path");
           return Optional.of(
               LocalRepositoryLookupValue.success(
-                  RepositoryName.create("@" + rule.getName()), PathFragment.create(path)));
+                  RepositoryName.create(rule.getName()), PathFragment.create(path)));
         } catch (LabelSyntaxException e) {
           // This shouldn't be possible if the rule name is valid, and it should already have been
           // validated.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredExecutionPlatformsFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredExecutionPlatformsFunction.java
index a68a382..617f8e8 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredExecutionPlatformsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredExecutionPlatformsFunction.java
@@ -169,7 +169,7 @@
       TargetPattern.Parser parser =
           new TargetPattern.Parser(
               PathFragment.EMPTY_FRAGMENT,
-              RepositoryName.createFromValidStrippedName(module.getCanonicalRepoName()),
+              RepositoryName.createUnvalidated(module.getCanonicalRepoName()),
               bazelModuleResolutionValue.getFullRepoMapping(module.getKey()));
       for (String pattern : module.getExecutionPlatformsToRegister()) {
         try {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunction.java
index b710fec..896ae39 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunction.java
@@ -159,7 +159,7 @@
       TargetPattern.Parser parser =
           new TargetPattern.Parser(
               PathFragment.EMPTY_FRAGMENT,
-              RepositoryName.createFromValidStrippedName(module.getCanonicalRepoName()),
+              RepositoryName.createUnvalidated(module.getCanonicalRepoName()),
               bazelModuleResolutionValue.getFullRepoMapping(module.getKey()));
       for (String pattern : module.getToolchainsToRegister()) {
         try {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunction.java
index 51a7dc8..57a19d5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunction.java
@@ -74,8 +74,8 @@
                             && !entry.getValue().getAssociatedRule().getRuleClass().equals("bind"))
                 .collect(
                     Collectors.toMap(
-                        entry -> RepositoryName.createFromValidStrippedName(entry.getKey()),
-                        entry -> RepositoryName.createFromValidStrippedName(entry.getKey())));
+                        entry -> RepositoryName.createUnvalidated(entry.getKey()),
+                        entry -> RepositoryName.createUnvalidated(entry.getKey())));
         return RepositoryMappingValue.withMapping(
             computeForBazelModuleRepo(repositoryName, bazelModuleResolutionValue)
                 .get()
@@ -163,9 +163,9 @@
         moduleExtensionResolutionValue.getExtensionIdToRepoInternalNames().get(extensionId).stream()
             .collect(
                 toImmutableMap(
-                    RepositoryName::createFromValidStrippedName,
+                    RepositoryName::createUnvalidated,
                     internalName ->
-                        RepositoryName.createFromValidStrippedName(
+                        RepositoryName.createUnvalidated(
                             extensionUniqueName + "." + internalName)));
     // Find the key of the module containing this extension. This will be used to compute additional
     // mappings -- any repo generated by an extension contained in the module "foo" can additionally
@@ -212,14 +212,14 @@
               ModuleKey moduleKey = moduleNameLookup.get(toRepo.getName());
               return moduleKey == null
                   ? toRepo
-                  : RepositoryName.createFromValidStrippedName(moduleKey.getCanonicalRepoName());
+                  : RepositoryName.createUnvalidated(moduleKey.getCanonicalRepoName());
             }));
     // If there's no existing mapping to "foo", we should add a mapping from "foo" to "foo.1.3"
     // anyways.
     for (Map.Entry<String, ModuleKey> entry : moduleNameLookup.entrySet()) {
       mapping.putIfAbsent(
-          RepositoryName.createFromValidStrippedName(entry.getKey()),
-          RepositoryName.createFromValidStrippedName(entry.getValue().getCanonicalRepoName()));
+          RepositoryName.createUnvalidated(entry.getKey()),
+          RepositoryName.createUnvalidated(entry.getValue().getCanonicalRepoName()));
     }
     return RepositoryMappingValue.withMapping(
         RepositoryMapping.createAllowingFallback(ImmutableMap.copyOf(mapping)));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/StarlarkBuiltinsValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/StarlarkBuiltinsValue.java
index 5d971ab..c8cdbcb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/StarlarkBuiltinsValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/StarlarkBuiltinsValue.java
@@ -15,7 +15,6 @@
 package com.google.devtools.build.lib.skyframe;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
 import com.google.devtools.build.skyframe.SkyFunctionName;
@@ -34,7 +33,7 @@
  */
 public final class StarlarkBuiltinsValue implements SkyValue {
 
-  static final String BUILTINS_NAME = "@_builtins";
+  static final String BUILTINS_NAME = "_builtins";
 
   /**
    * The builtins pseudo-repository.
@@ -47,20 +46,13 @@
    * and must match {@link #BUILTINS_NAME} exactly.
    */
   // TODO(#11437): Add actual enforcement that users cannot define a repo named "@_builtins".
-  @SerializationConstant static final RepositoryName BUILTINS_REPO;
+  @SerializationConstant
+  static final RepositoryName BUILTINS_REPO = RepositoryName.createUnvalidated(BUILTINS_NAME);
 
   /** Reports whether the given repository is the special builtins pseudo-repository. */
   static boolean isBuiltinsRepo(RepositoryName repo) {
     // Use String.equals(), not RepositoryName.equals(), to force case sensitivity.
-    return repo.getNameWithAt().equals(BUILTINS_NAME);
-  }
-
-  static {
-    try {
-      BUILTINS_REPO = RepositoryName.create(BUILTINS_NAME);
-    } catch (LabelSyntaxException e) {
-      throw new IllegalStateException(e);
-    }
+    return repo.getName().equals(BUILTINS_NAME);
   }
 
   // These are all (except transitiveDigest) deeply immutable since the Starlark values are already
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
index 6d303d0..9cb65a9 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
@@ -87,7 +87,7 @@
     barRelative = barPath.getRelative("barsource.txt");
 
     alienPath = PathFragment.create("external/alien");
-    alienPackage = PackageIdentifier.create("@alien", alienPath);
+    alienPackage = PackageIdentifier.create("alien", alienPath);
     alienRelative = alienPath.getRelative("alien.txt");
 
     artifactFactory = new ArtifactFactory(execRoot.getParentDirectory(), "bazel-out");
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/LocationExpanderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/LocationExpanderTest.java
index fdf64e6..dfe77aa 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/LocationExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/LocationExpanderTest.java
@@ -130,9 +130,8 @@
         .add("@bar//a", "/exec/src/a")
         .build();
 
-    ImmutableMap<RepositoryName, RepositoryName> repositoryMapping = ImmutableMap.of(
-        RepositoryName.create("@foo"),
-        RepositoryName.create("@bar"));
+    ImmutableMap<RepositoryName, RepositoryName> repositoryMapping =
+        ImmutableMap.of(RepositoryName.create("foo"), RepositoryName.create("bar"));
 
     LocationExpander locationExpander =
         new LocationExpander(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
index c333ad7..9f9b390 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/LocationFunctionTest.java
@@ -154,8 +154,8 @@
 
   @Test
   public void locationFunctionWithMappingReplace() throws Exception {
-    RepositoryName a = RepositoryName.create("@a");
-    RepositoryName b = RepositoryName.create("@b");
+    RepositoryName a = RepositoryName.create("a");
+    RepositoryName b = RepositoryName.create("b");
     ImmutableMap<RepositoryName, RepositoryName> repositoryMapping = ImmutableMap.of(a, b);
     LocationFunction func =
         new LocationFunctionBuilder("//foo", false).add("@b//foo", "/exec/src/bar").build();
@@ -165,8 +165,8 @@
 
   @Test
   public void locationFunctionWithMappingIgnoreRepo() throws Exception {
-    RepositoryName a = RepositoryName.create("@a");
-    RepositoryName b = RepositoryName.create("@b");
+    RepositoryName a = RepositoryName.create("a");
+    RepositoryName b = RepositoryName.create("b");
     ImmutableMap<RepositoryName, RepositoryName> repositoryMapping = ImmutableMap.of(a, b);
     LocationFunction func =
         new LocationFunctionBuilder("//foo", false).add("@potato//foo", "/exec/src/bar").build();
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationValueTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationValueTest.java
index e50d18f..63a8cc8 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationValueTest.java
@@ -389,20 +389,20 @@
     // these configurations are never trimmed nor even used to build targets so not an issue.
     new EqualsTester()
         .addEqualityGroup(
-            createRaw(parseBuildOptions("--test_arg=1a"), "@testrepo", false, ""),
-            createRaw(parseBuildOptions("--test_arg=1a"), "@testrepo", false, ""))
+            createRaw(parseBuildOptions("--test_arg=1a"), "testrepo", false, ""),
+            createRaw(parseBuildOptions("--test_arg=1a"), "testrepo", false, ""))
         // Different BuildOptions means non-equal
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=1b"), "@testrepo", false, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=1b"), "testrepo", false, ""))
         // Different --experimental_sibling_repository_layout means non-equal
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "@testrepo", true, ""))
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "@testrepo", false, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "testrepo", true, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=2"), "testrepo", false, ""))
         // Different repositoryName means non-equal
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "@testrepo1", false, ""))
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "@testrepo2", false, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "testrepo1", false, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "testrepo2", false, ""))
         // Different transitionDirectoryNameFragment means non-equal
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "@testrepo", false, ""))
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "@testrepo", false, "a"))
-        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "@testrepo", false, "b"))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "testrepo", false, ""))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "testrepo", false, "a"))
+        .addEqualityGroup(createRaw(parseBuildOptions("--test_arg=3"), "testrepo", false, "b"))
         .testEquals();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java
index ee7eea8..993ee90 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/BzlmodTestUtil.java
@@ -40,8 +40,8 @@
     ImmutableMap.Builder<RepositoryName, RepositoryName> mappingBuilder = ImmutableMap.builder();
     for (int i = 0; i < names.length; i += 2) {
       mappingBuilder.put(
-          RepositoryName.createFromValidStrippedName(names[i]),
-          RepositoryName.createFromValidStrippedName(names[i + 1]));
+          RepositoryName.createUnvalidated(names[i]),
+          RepositoryName.createUnvalidated(names[i + 1]));
     }
     return RepositoryMapping.create(mappingBuilder.buildOrThrow(), key.getCanonicalRepoName());
   }
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java
index 7160d46..305622f 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java
@@ -41,16 +41,14 @@
   @Test
   public void testOverrideConverter() throws Exception {
     RepositoryOverride actual = converter.convert("foo=/bar");
-    assertThat(actual.repositoryName())
-        .isEqualTo(RepositoryName.createFromValidStrippedName("foo"));
+    assertThat(actual.repositoryName()).isEqualTo(RepositoryName.createUnvalidated("foo"));
     assertThat(actual.path()).isEqualTo(PathFragment.create("/bar"));
   }
 
   @Test
   public void testOverridePathWithEqualsSign() throws Exception {
     RepositoryOverride actual = converter.convert("foo=/bar=/baz");
-    assertThat(actual.repositoryName())
-        .isEqualTo(RepositoryName.createFromValidStrippedName("foo"));
+    assertThat(actual.repositoryName()).isEqualTo(RepositoryName.createUnvalidated("foo"));
     assertThat(actual.path()).isEqualTo(PathFragment.create("/bar=/baz"));
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java
index 8be762c..842ae31 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/WorkspaceBlackBoxTest.java
@@ -261,7 +261,7 @@
     ProcessResult result = context().bazel().shouldFail().build("//...");
     assertThat(result.errString())
         .contains(
-            "invalid repository name '@@a': workspace names may contain only "
+            "invalid repository name '@@a': repo names may contain only "
                 + "A-Z, a-z, 0-9, '-', '_' and '.'");
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java b/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
index 4df48ae..e071655 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/SymlinkForestTest.java
@@ -168,7 +168,7 @@
       repoRoot.getRelative(pkg).createDirectoryAndParents();
       FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
     }
-    return PackageIdentifier.create(RepositoryName.create("@" + repo), PathFragment.create(pkg));
+    return PackageIdentifier.create(RepositoryName.create("" + repo), PathFragment.create(pkg));
   }
 
   // Create package for main repo
@@ -178,7 +178,7 @@
       repoRoot.getRelative(pkg).createDirectoryAndParents();
       FileSystemUtils.createEmptyFile(repoRoot.getRelative(pkg).getChild("file"));
     }
-    return PackageIdentifier.create(RepositoryName.create("@"), PathFragment.create(pkg));
+    return PackageIdentifier.create(RepositoryName.create(""), PathFragment.create(pkg));
   }
 
   private static void assertLinksTo(Path fromRoot, Root toRoot, String relpart) throws IOException {
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
index ba08e17..8ebfa71 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
@@ -133,22 +133,22 @@
 
   @Test
   public void testGetRelativeWithDifferentRepo() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelativeWithRemapping("@remote//x:y", ImmutableMap.of());
 
-    assertThat(relative.getRepository()).isEqualTo(RepositoryName.create("@remote"));
+    assertThat(relative.getRepository()).isEqualTo(RepositoryName.create("remote"));
     assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("x"));
     assertThat(relative.getName()).isEqualTo("y");
   }
 
   @Test
   public void testGetRelativeWithoutRemappingBaseLabel() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@a", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("a", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
     ImmutableMap<RepositoryName, RepositoryName> repoMapping =
-        ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b"));
+        ImmutableMap.of(RepositoryName.create("a"), RepositoryName.create("b"));
     Label relative = base.getRelativeWithRemapping(":y", repoMapping);
 
     // getRelative should only remap repositories passed in the string arg and not
@@ -159,10 +159,10 @@
 
   @Test
   public void testGetRelativeWithDifferentRepoAndRemapping() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
     ImmutableMap<RepositoryName, RepositoryName> repoMapping =
-        ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b"));
+        ImmutableMap.of(RepositoryName.create("a"), RepositoryName.create("b"));
     Label relative = base.getRelativeWithRemapping("@a//x:y", repoMapping);
 
     Label actual = Label.parseAbsoluteUnchecked("@b//x:y");
@@ -171,7 +171,7 @@
 
   @Test
   public void testGetRelativeWithRepoLocalAbsoluteLabel() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelativeWithRemapping("//x:y", ImmutableMap.of());
@@ -183,7 +183,7 @@
 
   @Test
   public void testGetRelativeWithLocalRepoRelativeLabel() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelativeWithRemapping(":y", ImmutableMap.of());
@@ -195,7 +195,7 @@
 
   @Test
   public void testGetRelativeWithRepoAndReservedPackage() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative =
@@ -210,12 +210,12 @@
 
   @Test
   public void testGetRelativeWithRemoteRepoToDefaultRepo() throws Exception {
-    PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo"));
+    PackageIdentifier packageId = PackageIdentifier.create("repo", PathFragment.create("foo"));
     Label base = Label.create(packageId, "bar");
 
     Label relative = base.getRelativeWithRemapping("@//x:y", ImmutableMap.of());
 
-    assertThat(relative.getRepository()).isEqualTo(RepositoryName.create("@"));
+    assertThat(relative.getRepository()).isEqualTo(RepositoryName.create(""));
     assertThat(relative.getPackageFragment()).isEqualTo(PathFragment.create("x"));
     assertThat(relative.getName()).isEqualTo("y");
   }
@@ -422,7 +422,7 @@
             LabelSyntaxException.class, () -> Label.parseAbsolute("@foo:xyz", ImmutableMap.of()));
     assertThat(e)
         .hasMessageThat()
-        .containsMatch("invalid repository name '@foo:xyz': workspace names may contain only");
+        .containsMatch("invalid repository name '@foo:xyz': repo names may contain only");
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
index 0cc7912..d781332 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/PackageIdentifierTest.java
@@ -57,16 +57,16 @@
   public void testToString() throws Exception {
     PackageIdentifier local = PackageIdentifier.create("", PathFragment.create("bar/baz"));
     assertThat(local.toString()).isEqualTo("bar/baz");
-    PackageIdentifier external = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
+    PackageIdentifier external = PackageIdentifier.create("foo", PathFragment.create("bar/baz"));
     assertThat(external.toString()).isEqualTo("@foo//bar/baz");
   }
 
   @Test
   public void testCompareTo() throws Exception {
-    PackageIdentifier foo1 = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
-    PackageIdentifier foo2 = PackageIdentifier.create("@foo", PathFragment.create("bar/baz"));
-    PackageIdentifier foo3 = PackageIdentifier.create("@foo", PathFragment.create("bar/bz"));
-    PackageIdentifier bar = PackageIdentifier.create("@bar", PathFragment.create("bar/baz"));
+    PackageIdentifier foo1 = PackageIdentifier.create("foo", PathFragment.create("bar/baz"));
+    PackageIdentifier foo2 = PackageIdentifier.create("foo", PathFragment.create("bar/baz"));
+    PackageIdentifier foo3 = PackageIdentifier.create("foo", PathFragment.create("bar/bz"));
+    PackageIdentifier bar = PackageIdentifier.create("bar", PathFragment.create("bar/baz"));
     assertThat(foo1.compareTo(foo2)).isEqualTo(0);
     assertThat(foo1.compareTo(foo3)).isLessThan(0);
     assertThat(foo1.compareTo(bar)).isGreaterThan(0);
@@ -75,22 +75,22 @@
   @Test
   public void testInvalidPackageName() throws Exception {
     // This shouldn't throw an exception, package names aren't validated.
-    PackageIdentifier.create("@foo", PathFragment.create("bar.baz"));
+    PackageIdentifier.create("foo", PathFragment.create("bar.baz"));
   }
 
   @Test
   public void testPackageFragmentEquality() throws Exception {
     // Make sure package fragments are canonicalized.
-    PackageIdentifier p1 = PackageIdentifier.create("@whatever", PathFragment.create("foo/bar"));
-    PackageIdentifier p2 = PackageIdentifier.create("@whatever", PathFragment.create("foo/bar"));
+    PackageIdentifier p1 = PackageIdentifier.create("whatever", PathFragment.create("foo/bar"));
+    PackageIdentifier p2 = PackageIdentifier.create("whatever", PathFragment.create("foo/bar"));
     assertThat(p1.getPackageFragment()).isSameInstanceAs(p2.getPackageFragment());
   }
 
   @Test
   public void testRunfilesDir() throws Exception {
-    assertThat(PackageIdentifier.create("@foo", PathFragment.create("bar/baz")).getRunfilesPath())
+    assertThat(PackageIdentifier.create("foo", PathFragment.create("bar/baz")).getRunfilesPath())
         .isEqualTo(PathFragment.create("../foo/bar/baz"));
-    assertThat(PackageIdentifier.create("@", PathFragment.create("bar/baz")).getRunfilesPath())
+    assertThat(PackageIdentifier.create("", PathFragment.create("bar/baz")).getRunfilesPath())
         .isEqualTo(PathFragment.create("bar/baz"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryMappingTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryMappingTest.java
index ec6c179..e2e8f6c 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryMappingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryMappingTest.java
@@ -29,45 +29,44 @@
   public void maybeFallback() throws Exception {
     RepositoryMapping mapping =
         RepositoryMapping.createAllowingFallback(
-            ImmutableMap.of(RepositoryName.create("@A"), RepositoryName.create("@com_foo_bar_a")));
-    assertThat(mapping.get(RepositoryName.create("@A")))
-        .isEqualTo(RepositoryName.create("@com_foo_bar_a"));
-    assertThat(mapping.get(RepositoryName.create("@B"))).isEqualTo(RepositoryName.create("@B"));
+            ImmutableMap.of(RepositoryName.create("A"), RepositoryName.create("com_foo_bar_a")));
+    assertThat(mapping.get(RepositoryName.create("A")))
+        .isEqualTo(RepositoryName.create("com_foo_bar_a"));
+    assertThat(mapping.get(RepositoryName.create("B"))).isEqualTo(RepositoryName.create("B"));
   }
 
   @Test
   public void neverFallback() throws Exception {
     RepositoryMapping mapping =
         RepositoryMapping.create(
-            ImmutableMap.of(RepositoryName.create("@A"), RepositoryName.create("@com_foo_bar_a")),
+            ImmutableMap.of(RepositoryName.create("A"), RepositoryName.create("com_foo_bar_a")),
             "fake_owner_repo");
-    assertThat(mapping.get(RepositoryName.create("@A")))
-        .isEqualTo(RepositoryName.create("@com_foo_bar_a"));
-    assertThat(mapping.get(RepositoryName.create("@B")))
-        .isEqualTo(RepositoryName.create("@B").toNonVisible("fake_owner_repo"));
+    assertThat(mapping.get(RepositoryName.create("A")))
+        .isEqualTo(RepositoryName.create("com_foo_bar_a"));
+    assertThat(mapping.get(RepositoryName.create("B")))
+        .isEqualTo(RepositoryName.create("B").toNonVisible("fake_owner_repo"));
 
     // Special repos should still be visible
-    assertThat(mapping.get(RepositoryName.create("@bazel_tools")))
-        .isEqualTo(RepositoryName.create("@bazel_tools"));
-    assertThat(mapping.get(RepositoryName.create("@local_config_platform")))
-        .isEqualTo(RepositoryName.create("@local_config_platform"));
+    assertThat(mapping.get(RepositoryName.create("bazel_tools")))
+        .isEqualTo(RepositoryName.create("bazel_tools"));
+    assertThat(mapping.get(RepositoryName.create("local_config_platform")))
+        .isEqualTo(RepositoryName.create("local_config_platform"));
   }
 
   @Test
   public void additionalMappings() throws Exception {
     RepositoryMapping mapping =
         RepositoryMapping.create(
-                ImmutableMap.of(
-                    RepositoryName.create("@A"), RepositoryName.create("@com_foo_bar_a")),
+                ImmutableMap.of(RepositoryName.create("A"), RepositoryName.create("com_foo_bar_a")),
                 "fake_owner_repo")
             .withAdditionalMappings(
                 ImmutableMap.of(
-                    RepositoryName.create("@B"), RepositoryName.create("@com_foo_bar_b")));
-    assertThat(mapping.get(RepositoryName.create("@A")))
-        .isEqualTo(RepositoryName.create("@com_foo_bar_a"));
-    assertThat(mapping.get(RepositoryName.create("@B")))
-        .isEqualTo(RepositoryName.create("@com_foo_bar_b"));
-    assertThat(mapping.get(RepositoryName.create("@C")))
-        .isEqualTo(RepositoryName.create("@C").toNonVisible("fake_owner_repo"));
+                    RepositoryName.create("B"), RepositoryName.create("com_foo_bar_b")));
+    assertThat(mapping.get(RepositoryName.create("A")))
+        .isEqualTo(RepositoryName.create("com_foo_bar_a"));
+    assertThat(mapping.get(RepositoryName.create("B")))
+        .isEqualTo(RepositoryName.create("com_foo_bar_b"));
+    assertThat(mapping.get(RepositoryName.create("C")))
+        .isEqualTo(RepositoryName.create("C").toNonVisible("fake_owner_repo"));
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
index fc3141a..1a0002a 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/RepositoryNameTest.java
@@ -36,30 +36,28 @@
 
   @Test
   public void testValidateRepositoryName() throws Exception {
-    assertThat(RepositoryName.create("@foo").toString()).isEqualTo("@foo");
+    assertThat(RepositoryName.create("foo").toString()).isEqualTo("@foo");
     assertThat(RepositoryName.create("").toString()).isEqualTo("@");
     assertThat(RepositoryName.create("")).isSameInstanceAs(RepositoryName.MAIN);
-    assertThat(RepositoryName.create("@foo_bar").toString()).isEqualTo("@foo_bar");
-    assertThat(RepositoryName.create("@foo-bar").toString()).isEqualTo("@foo-bar");
-    assertThat(RepositoryName.create("@foo.bar").toString()).isEqualTo("@foo.bar");
-    assertThat(RepositoryName.create("@..foo").toString()).isEqualTo("@..foo");
-    assertThat(RepositoryName.create("@foo..").toString()).isEqualTo("@foo..");
-    assertThat(RepositoryName.create("@.foo").toString()).isEqualTo("@.foo");
+    assertThat(RepositoryName.create("foo_bar").toString()).isEqualTo("@foo_bar");
+    assertThat(RepositoryName.create("foo-bar").toString()).isEqualTo("@foo-bar");
+    assertThat(RepositoryName.create("foo.bar").toString()).isEqualTo("@foo.bar");
+    assertThat(RepositoryName.create("..foo").toString()).isEqualTo("@..foo");
+    assertThat(RepositoryName.create("foo..").toString()).isEqualTo("@foo..");
+    assertThat(RepositoryName.create(".foo").toString()).isEqualTo("@.foo");
 
-    assertNotValid("x", "workspace names must start with '@'");
-    assertNotValid("@.", "workspace names are not allowed to be '@.'");
-    assertNotValid("@..", "workspace names are not allowed to be '@..'");
-    assertNotValid("@foo/bar", "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
-    assertNotValid("@foo@", "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
-    assertNotValid("@foo\0", "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
+    assertNotValid(".", "repo names are not allowed to be '@.'");
+    assertNotValid("..", "repo names are not allowed to be '@..'");
+    assertNotValid("foo/bar", "repo names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
+    assertNotValid("foo@", "repo names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
+    assertNotValid("foo\0", "repo names may contain only A-Z, a-z, 0-9, '-', '_' and '.'");
   }
 
   @Test
   public void testRunfilesDir() throws Exception {
-    assertThat(RepositoryName.create("@foo").getRunfilesPath())
+    assertThat(RepositoryName.create("foo").getRunfilesPath())
         .isEqualTo(PathFragment.create("../foo"));
-    assertThat(RepositoryName.create("@").getRunfilesPath())
-        .isEqualTo(PathFragment.EMPTY_FRAGMENT);
+    assertThat(RepositoryName.create("").getRunfilesPath()).isEqualTo(PathFragment.EMPTY_FRAGMENT);
     assertThat(RepositoryName.create("").getRunfilesPath())
         .isEqualTo(PathFragment.EMPTY_FRAGMENT);
   }
@@ -67,7 +65,7 @@
   @Test
   public void testGetDefaultCanonicalForm() throws Exception {
     assertThat(RepositoryName.create("").getCanonicalForm()).isEqualTo("");
-    assertThat(RepositoryName.create("@").getCanonicalForm()).isEqualTo("");
-    assertThat(RepositoryName.create("@foo").getCanonicalForm()).isEqualTo("@foo");
+    assertThat(RepositoryName.create("").getCanonicalForm()).isEqualTo("");
+    assertThat(RepositoryName.create("foo").getCanonicalForm()).isEqualTo("@foo");
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/TargetPatternTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/TargetPatternTest.java
index 2e7a86f..64963ba 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/TargetPatternTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/TargetPatternTest.java
@@ -170,13 +170,11 @@
     RepositoryMapping renaming =
         RepositoryMapping.createAllowingFallback(
             ImmutableMap.of(
-                RepositoryName.create("@foo"), RepositoryName.create("@bar"),
-                RepositoryName.create("@myworkspace"), RepositoryName.create("@")));
+                RepositoryName.create("foo"), RepositoryName.create("bar"),
+                RepositoryName.create("myworkspace"), RepositoryName.create("")));
     TargetPattern.Parser parser =
         new TargetPattern.Parser(
-            PathFragment.EMPTY_FRAGMENT,
-            RepositoryName.createFromValidStrippedName("myrepo"),
-            renaming);
+            PathFragment.EMPTY_FRAGMENT, RepositoryName.createUnvalidated("myrepo"), renaming);
 
     // Expecting renaming
     assertThat(parser.parse("@foo//package:target").getRepository().getName()).isEqualTo("bar");
diff --git a/src/test/java/com/google/devtools/build/lib/packages/LabelConverterTest.java b/src/test/java/com/google/devtools/build/lib/packages/LabelConverterTest.java
index 87ef76b..2e3494a 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/LabelConverterTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/LabelConverterTest.java
@@ -37,7 +37,7 @@
             currentRule,
             RepositoryMapping.createAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.create("@orig_repo"), RepositoryName.create("@new_repo"))),
+                    RepositoryName.create("orig_repo"), RepositoryName.create("new_repo"))),
             /* labelCache= */ new HashMap<>());
     Label label = BuildType.LABEL.convert("@orig_repo//foo:bar", null, context);
     assertThat(label)
diff --git a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java
index e48acfc..4754764 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java
@@ -140,7 +140,7 @@
         "    path = '/foo',",
         "    repo_mapping = {'@x' : '@y'},",
         ")");
-    assertMapping(helper, "@foo", "@x", "@y");
+    assertMapping(helper, "foo", "x", "y");
   }
 
   @Test
@@ -156,8 +156,8 @@
         "    path = '/bar',",
         "    repo_mapping = {'@a' : '@b'},",
         ")");
-    assertMapping(helper, "@foo", "@x", "@y");
-    assertMapping(helper, "@bar", "@a", "@b");
+    assertMapping(helper, "foo", "x", "y");
+    assertMapping(helper, "bar", "a", "b");
   }
 
   @Test
@@ -168,9 +168,9 @@
         "    path = '/foo',",
         "    repo_mapping = {'@a' : '@b', '@c' : '@d', '@e' : '@f'},",
         ")");
-    assertMapping(helper, "@foo", "@a", "@b");
-    assertMapping(helper, "@foo", "@c", "@d");
-    assertMapping(helper, "@foo", "@e", "@f");
+    assertMapping(helper, "foo", "a", "b");
+    assertMapping(helper, "foo", "c", "d");
+    assertMapping(helper, "foo", "e", "f");
   }
 
   @Test
@@ -181,7 +181,7 @@
         "    path = '/foo',",
         "    repo_mapping = {},",
         ")");
-    assertThat(helper.getPackage().getRepositoryMapping(RepositoryName.create("@foo"))).isEmpty();
+    assertThat(helper.getPackage().getRepositoryMapping(RepositoryName.create("foo"))).isEmpty();
   }
 
   @Test
@@ -200,13 +200,13 @@
   @Test
   public void testImplicitMainRepoRename() throws Exception {
     helper.parse("workspace(name = 'foo')");
-    assertMapping(helper, "@", "@foo", "@");
+    assertMapping(helper, "", "foo", "");
   }
 
   @Test
   public void testEmptyRepositoryHasEmptyMap() throws Exception {
     helper.parse("");
-    assertThat(helper.getPackage().getRepositoryMapping(RepositoryName.create("@"))).isEmpty();
+    assertThat(helper.getPackage().getRepositoryMapping(RepositoryName.create(""))).isEmpty();
   }
 
   @Test
@@ -218,8 +218,8 @@
         "    path = '/foo',",
         "    repo_mapping = {'@x' : '@y', '@bar' : '@newname'},",
         ")");
-    assertMapping(helper, "@foo", "@x", "@y");
-    assertMapping(helper, "@foo", "@bar", "@newname");
+    assertMapping(helper, "foo", "x", "y");
+    assertMapping(helper, "foo", "bar", "newname");
   }
 
   private void assertMapping(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
index 19315ff..f6c5b9b 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
@@ -148,7 +148,7 @@
   /** Checks the behavior of {@link ConfigSetting#isUnderToolsPackage}. */
   @Test
   public void isUnderToolsPackage() throws Exception {
-    RepositoryName toolsRepo = RepositoryName.create("@tools");
+    RepositoryName toolsRepo = RepositoryName.create("tools");
     // Subpackage of the tools package.
     assertThat(
             ConfigSetting.isUnderToolsPackage(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
index 1b9f403..156c3cb 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
@@ -370,7 +370,7 @@
     assertThat(ccCompilationContext.getIncludeDirs())
         .contains(
             getConfiguration(target)
-                .getGenfilesFragment(RepositoryName.create("@bla"))
+                .getGenfilesFragment(RepositoryName.create("bla"))
                 .getRelative("external/bla"));
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
index 8e7ed10..bd2eca5 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java
@@ -442,7 +442,7 @@
     String genfiles =
         getTargetConfiguration()
             .getGenfilesFragment(
-                siblingRepoLayout ? RepositoryName.create("@foo") : RepositoryName.MAIN)
+                siblingRepoLayout ? RepositoryName.create("foo") : RepositoryName.MAIN)
             .toString();
     String fooProtoRoot;
     if (useVirtualImports) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java
index 5ee30c7..d946a09 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java
@@ -273,11 +273,10 @@
   public void testOverride() throws Exception {
     RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set(
         differencer,
-        ImmutableMap.of(
-            RepositoryName.createFromValidStrippedName("foo"), overrideDirectory.asFragment()));
+        ImmutableMap.of(RepositoryName.createUnvalidated("foo"), overrideDirectory.asFragment()));
 
     StoredEventHandler eventHandler = new StoredEventHandler();
-    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName("foo"));
+    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createUnvalidated("foo"));
     EvaluationContext evaluationContext =
         EvaluationContext.newBuilder()
             .setKeepGoing(false)
@@ -302,7 +301,7 @@
 
     RepositoryDirectoryDirtinessChecker checker =
         new RepositoryDirectoryDirtinessChecker(rootPath, knowledge);
-    RepositoryName repositoryName = RepositoryName.create("@repo");
+    RepositoryName repositoryName = RepositoryName.create("repo");
     RepositoryDirectoryValue.Key key = RepositoryDirectoryValue.key(repositoryName);
 
     SuccessfulRepositoryDirectoryValue usual =
@@ -322,7 +321,7 @@
 
     assertThat(checker.check(key, fetchDelayed, SyscallCache.NO_CACHE, tsgm).isDirty()).isTrue();
 
-    RepositoryName managedName = RepositoryName.create("@managed");
+    RepositoryName managedName = RepositoryName.create("managed");
     RepositoryDirectoryValue.Key managedKey = RepositoryDirectoryValue.key(managedName);
     SuccessfulRepositoryDirectoryValue withManagedDirectories =
         RepositoryDirectoryValue.builder()
@@ -373,7 +372,7 @@
     // That's why we will directly fill managed directories value (the corresponding structure
     // is passed to RepositoryDelegatorFunction during construction).
     managedDirectoriesKnowledge.setManagedDirectories(
-        ImmutableMap.of(PathFragment.create("dir1"), RepositoryName.create("@repo1")));
+        ImmutableMap.of(PathFragment.create("dir1"), RepositoryName.create("repo1")));
 
     loadRepo("repo1");
 
@@ -401,9 +400,9 @@
     managedDirectoriesKnowledge.setManagedDirectories(
         ImmutableMap.of(
             PathFragment.create("dir1"),
-            RepositoryName.create("@repo1"),
+            RepositoryName.create("repo1"),
             PathFragment.create("dir2"),
-            RepositoryName.create("@repo1")));
+            RepositoryName.create("repo1")));
     loadRepo("repo1");
 
     assertThat(testStarlarkRepositoryFunction.isFetchCalled()).isTrue();
@@ -443,7 +442,7 @@
         "broken_repo(name = 'broken')");
 
     StoredEventHandler eventHandler = new StoredEventHandler();
-    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName("broken"));
+    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createUnvalidated("broken"));
     // Make it be evaluated every time, as we are testing evaluation.
     differencer.invalidate(ImmutableSet.of(key));
     EvaluationContext evaluationContext =
@@ -468,7 +467,7 @@
     scratch.overwriteFile(rootPath.getRelative("WORKSPACE").getPathString(), "");
 
     StoredEventHandler eventHandler = new StoredEventHandler();
-    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName("foo"));
+    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createUnvalidated("foo"));
     // Make it be evaluated every time, as we are testing evaluation.
     differencer.invalidate(ImmutableSet.of(key));
     EvaluationContext evaluationContext =
@@ -514,7 +513,7 @@
         "fictive_repo_rule(name = 'B.1.0')");
 
     StoredEventHandler eventHandler = new StoredEventHandler();
-    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName("B.1.0"));
+    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createUnvalidated("B.1.0"));
     EvaluationContext evaluationContext =
         EvaluationContext.newBuilder()
             .setKeepGoing(false)
@@ -542,7 +541,7 @@
     StoredEventHandler eventHandler = new StoredEventHandler();
     SkyKey key =
         RepositoryDirectoryValue.key(
-            RepositoryName.createFromValidStrippedName("foo").toNonVisible("fake_owner_repo"));
+            RepositoryName.createUnvalidated("foo").toNonVisible("fake_owner_repo"));
     EvaluationContext evaluationContext =
         EvaluationContext.newBuilder()
             .setKeepGoing(false)
@@ -561,8 +560,7 @@
 
   private void loadRepo(String strippedRepoName) throws InterruptedException {
     StoredEventHandler eventHandler = new StoredEventHandler();
-    SkyKey key =
-        RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName(strippedRepoName));
+    SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createUnvalidated(strippedRepoName));
     // Make it be evaluated every time, as we are testing evaluation.
     differencer.invalidate(ImmutableSet.of(key));
     EvaluationContext evaluationContext =
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
index 9110ce0..fc451d3 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
@@ -947,7 +947,7 @@
     BuildConfigurationValue configuration =
         BuildConfigurationValue.create(
             defaultBuildOptions,
-            RepositoryName.createFromValidStrippedName("workspace"),
+            RepositoryName.createUnvalidated("workspace"),
             /*siblingRepositoryLayout=*/ false,
             /*transitionDirectoryNameFragment=*/ "",
             new BlazeDirectories(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java
index b03e815..08441ec 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java
@@ -245,10 +245,10 @@
     scratch.file("a/b/BUILD");
     ContainingPackageLookupValue value =
         lookupContainingPackage(
-            PackageIdentifier.create(RepositoryName.create("@a"), PathFragment.create("b")));
+            PackageIdentifier.create(RepositoryName.create("a"), PathFragment.create("b")));
     assertThat(value.hasContainingPackage()).isTrue();
     assertThat(value.getContainingPackageName())
-        .isEqualTo(PackageIdentifier.create(RepositoryName.create("@a"), PathFragment.create("b")));
+        .isEqualTo(PackageIdentifier.create(RepositoryName.create("a"), PathFragment.create("b")));
   }
 
   @Test
@@ -260,7 +260,7 @@
     ContainingPackageLookupValue value = lookupContainingPackage("a/b");
     assertThat(value.hasContainingPackage()).isTrue();
     assertThat(value.getContainingPackageName())
-        .isEqualTo(PackageIdentifier.create(RepositoryName.create("@a"), PathFragment.create("b")));
+        .isEqualTo(PackageIdentifier.create(RepositoryName.create("a"), PathFragment.create("b")));
   }
 
   @Test
@@ -292,7 +292,7 @@
   @Test
   public void testNonExistentExternalRepositoryErrorReason() throws Exception {
     PackageIdentifier identifier =
-        PackageIdentifier.create("@some_repo", PathFragment.create(":atarget"));
+        PackageIdentifier.create("some_repo", PathFragment.create(":atarget"));
     ContainingPackageLookupValue value = lookupContainingPackage(identifier);
     assertThat(value.hasContainingPackage()).isFalse();
     assertThat(value.getClass()).isEqualTo(NoContainingPackage.class);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
index d2e7753..d0fba51 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
@@ -35,13 +35,13 @@
     SerializationTester serializationTester =
         new SerializationTester(
                 GlobDescriptor.create(
-                    PackageIdentifier.create("@foo", PathFragment.create("//bar")),
+                    PackageIdentifier.create("foo", PathFragment.create("//bar")),
                     Root.fromPath(FsUtils.TEST_FILESYSTEM.getPath("/packageRoot")),
                     PathFragment.create("subdir"),
                     "pattern",
                     Globber.Operation.FILES_AND_DIRS),
                 GlobDescriptor.create(
-                    PackageIdentifier.create("@bar", PathFragment.create("//foo")),
+                    PackageIdentifier.create("bar", PathFragment.create("//foo")),
                     Root.fromPath(FsUtils.TEST_FILESYSTEM.getPath("/anotherPackageRoot")),
                     PathFragment.create("anotherSubdir"),
                     "pattern",
@@ -59,7 +59,7 @@
   public void testCreateReturnsInternedInstances() throws LabelSyntaxException {
     GlobDescriptor original =
         GlobDescriptor.create(
-            PackageIdentifier.create("@foo", PathFragment.create("//bar")),
+            PackageIdentifier.create("foo", PathFragment.create("//bar")),
             Root.fromPath(FsUtils.TEST_FILESYSTEM.getPath("/packageRoot")),
             PathFragment.create("subdir"),
             "pattern",
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
index 7237ab6..1a3f037 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
@@ -376,7 +376,7 @@
 
     // First, use the correct label.
     PackageLookupValue packageLookupValue =
-        lookupPackage(PackageIdentifier.create("@local", PathFragment.EMPTY_FRAGMENT));
+        lookupPackage(PackageIdentifier.create("local", PathFragment.EMPTY_FRAGMENT));
     assertThat(packageLookupValue.packageExists()).isTrue();
 
     // Then, use the incorrect label.
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunctionTest.java
index adb5aa5..deeb101 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/RepositoryMappingFunctionTest.java
@@ -94,7 +94,7 @@
     ImmutableMap.Builder<RepositoryName, RepositoryName> allMappings = ImmutableMap.builder();
     allMappings.putAll(repositoryMapping);
     for (String name : analysisMock.getWorkspaceRepos()) {
-      RepositoryName repoName = RepositoryName.createFromValidStrippedName(name);
+      RepositoryName repoName = RepositoryName.createUnvalidated(name);
       allMappings.put(repoName, repoName);
     }
     return RepositoryMappingValue.withMapping(
@@ -110,7 +110,7 @@
         "    path = '/a_remote_repo',",
         "    repo_mapping = {'@a' : '@b'},",
         ")");
-    RepositoryName name = RepositoryName.create("@a_remote_repo");
+    RepositoryName name = RepositoryName.create("a_remote_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     EvaluationResult<RepositoryMappingValue> result = eval(skyKey);
 
@@ -120,10 +120,10 @@
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.create("@a"),
-                    RepositoryName.create("@b"),
-                    RepositoryName.create("@good"),
-                    RepositoryName.create("@"))));
+                    RepositoryName.create("a"),
+                    RepositoryName.create("b"),
+                    RepositoryName.create("good"),
+                    RepositoryName.create(""))));
   }
 
   @Test
@@ -144,12 +144,12 @@
         .isEqualTo(
             withMappingForRootModule(
                 ImmutableMap.of(
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@A"),
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@com_foo_bar_b"),
-                    RepositoryName.create("@B.1.0")),
+                    RepositoryName.create(""),
+                    RepositoryName.create(""),
+                    RepositoryName.create("A"),
+                    RepositoryName.create(""),
+                    RepositoryName.create("com_foo_bar_b"),
+                    RepositoryName.create("B.1.0")),
                 name));
   }
 
@@ -167,7 +167,7 @@
             "module(name='C', version='1.0')",
             "bazel_dep(name='B', version='1.0', repo_name='com_foo_bar_b')");
 
-    RepositoryName name = RepositoryName.create("@C.1.0");
+    RepositoryName name = RepositoryName.create("C.1.0");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     EvaluationResult<RepositoryMappingValue> result = eval(skyKey);
 
@@ -177,10 +177,10 @@
         .isEqualTo(
             withMapping(
                 ImmutableMap.of(
-                    RepositoryName.create("@C"),
-                    RepositoryName.create("@C.1.0"),
-                    RepositoryName.create("@com_foo_bar_b"),
-                    RepositoryName.create("@B.1.0")),
+                    RepositoryName.create("C"),
+                    RepositoryName.create("C.1.0"),
+                    RepositoryName.create("com_foo_bar_b"),
+                    RepositoryName.create("B.1.0")),
                 name));
   }
 
@@ -193,7 +193,7 @@
         "module(name='B', version='1.0')",
         "bazel_dep(name='A',version='3.0')");
 
-    RepositoryName name = RepositoryName.create("@B.1.0");
+    RepositoryName name = RepositoryName.create("B.1.0");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     EvaluationResult<RepositoryMappingValue> result = eval(skyKey);
 
@@ -203,10 +203,10 @@
         .isEqualTo(
             withMapping(
                 ImmutableMap.of(
-                    RepositoryName.create("@B"),
-                    RepositoryName.create("@B.1.0"),
-                    RepositoryName.create("@A"),
-                    RepositoryName.create("@")),
+                    RepositoryName.create("B"),
+                    RepositoryName.create("B.1.0"),
+                    RepositoryName.create("A"),
+                    RepositoryName.create("")),
                 name));
   }
 
@@ -234,14 +234,14 @@
         .isEqualTo(
             withMappingForRootModule(
                 ImmutableMap.of(
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@A"),
-                    RepositoryName.create("@"),
-                    RepositoryName.create("@B1"),
-                    RepositoryName.create("@B.1.0"),
-                    RepositoryName.create("@B2"),
-                    RepositoryName.create("@B.2.0")),
+                    RepositoryName.create(""),
+                    RepositoryName.create(""),
+                    RepositoryName.create("A"),
+                    RepositoryName.create(""),
+                    RepositoryName.create("B1"),
+                    RepositoryName.create("B.1.0"),
+                    RepositoryName.create("B2"),
+                    RepositoryName.create("B.2.0")),
                 name));
   }
 
@@ -263,7 +263,7 @@
         .addModule(createModuleKey("D", "1.0"), "module(name='D', version='1.0')")
         .addModule(createModuleKey("D", "2.0"), "module(name='D', version='2.0')");
 
-    RepositoryName name = RepositoryName.create("@B.1.0");
+    RepositoryName name = RepositoryName.create("B.1.0");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     EvaluationResult<RepositoryMappingValue> result = eval(skyKey);
 
@@ -275,8 +275,8 @@
         .isEqualTo(
             withMapping(
                 ImmutableMap.of(
-                    RepositoryName.create("@B"), RepositoryName.create("@B.1.0"),
-                    RepositoryName.create("@D"), RepositoryName.create("@D.1.0")),
+                    RepositoryName.create("B"), RepositoryName.create("B.1.0"),
+                    RepositoryName.create("D"), RepositoryName.create("D.1.0")),
                 name));
   }
 
@@ -296,7 +296,7 @@
         .addModule(createModuleKey("B", "2.0"), "module(name='B', version='2.0')")
         .addModule(createModuleKey("C", "1.0"), "module(name='C', version='1.0')");
 
-    RepositoryName name = RepositoryName.create("@B.1.0");
+    RepositoryName name = RepositoryName.create("B.1.0");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     EvaluationResult<RepositoryMappingValue> result = eval(skyKey);
 
@@ -308,8 +308,8 @@
         .isEqualTo(
             withMapping(
                 ImmutableMap.of(
-                    RepositoryName.create("@B"), RepositoryName.create("@B.1.0"),
-                    RepositoryName.create("@com_foo_bar_c"), RepositoryName.create("@C.1.0")),
+                    RepositoryName.create("B"), RepositoryName.create("B.1.0"),
+                    RepositoryName.create("com_foo_bar_c"), RepositoryName.create("C.1.0")),
                 name));
   }
 
@@ -327,9 +327,9 @@
         "    path = '/other_remote_repo',",
         "    repo_mapping = {'@x' : '@y'},",
         ")");
-    RepositoryName name1 = RepositoryName.create("@a_remote_repo");
+    RepositoryName name1 = RepositoryName.create("a_remote_repo");
     SkyKey skyKey1 = RepositoryMappingValue.key(name1);
-    RepositoryName name2 = RepositoryName.create("@other_remote_repo");
+    RepositoryName name2 = RepositoryName.create("other_remote_repo");
     SkyKey skyKey2 = RepositoryMappingValue.key(name2);
 
     assertThatEvaluationResult(eval(skyKey1))
@@ -337,19 +337,19 @@
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.create("@a"),
-                    RepositoryName.create("@b"),
-                    RepositoryName.create("@good"),
-                    RepositoryName.create("@"))));
+                    RepositoryName.create("a"),
+                    RepositoryName.create("b"),
+                    RepositoryName.create("good"),
+                    RepositoryName.create(""))));
     assertThatEvaluationResult(eval(skyKey2))
         .hasEntryThat(skyKey2)
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.create("@x"),
-                    RepositoryName.create("@y"),
-                    RepositoryName.create("@good"),
-                    RepositoryName.create("@"))));
+                    RepositoryName.create("x"),
+                    RepositoryName.create("y"),
+                    RepositoryName.create("good"),
+                    RepositoryName.create(""))));
   }
 
   @Test
@@ -361,7 +361,7 @@
         "    path = '/a_remote_repo',",
         "    repo_mapping = {'@a' : '@b', '@x' : '@y'},",
         ")");
-    RepositoryName name = RepositoryName.create("@a_remote_repo");
+    RepositoryName name = RepositoryName.create("a_remote_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
 
     assertThatEvaluationResult(eval(skyKey))
@@ -369,12 +369,12 @@
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.create("@a"),
-                    RepositoryName.create("@b"),
-                    RepositoryName.create("@x"),
-                    RepositoryName.create("@y"),
-                    RepositoryName.create("@good"),
-                    RepositoryName.create("@"))));
+                    RepositoryName.create("a"),
+                    RepositoryName.create("b"),
+                    RepositoryName.create("x"),
+                    RepositoryName.create("y"),
+                    RepositoryName.create("good"),
+                    RepositoryName.create(""))));
   }
 
   @Test
@@ -407,25 +407,25 @@
         .addModule(createModuleKey("D", "1.0"), "module(name='D', version='1.0')")
         .addModule(createModuleKey("D", "2.0"), "module(name='D', version='2.0')");
 
-    RepositoryName name = RepositoryName.create("@ws_repo");
+    RepositoryName name = RepositoryName.create("ws_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
     assertThatEvaluationResult(eval(skyKey))
         .hasEntryThat(skyKey)
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.<RepositoryName, RepositoryName>builder()
-                    .put(RepositoryName.create("@root"), RepositoryName.MAIN)
+                    .put(RepositoryName.create("root"), RepositoryName.MAIN)
                     // mappings to @B get remapped to @B.1.0 because of module B@1.0
-                    .put(RepositoryName.create("@B_alias"), RepositoryName.create("@B.1.0"))
-                    .put(RepositoryName.create("@B_alias2"), RepositoryName.create("@B.1.0"))
+                    .put(RepositoryName.create("B_alias"), RepositoryName.create("B.1.0"))
+                    .put(RepositoryName.create("B_alias2"), RepositoryName.create("B.1.0"))
                     // mapping from @B to @B.1.0 is also created
-                    .put(RepositoryName.create("@B"), RepositoryName.create("@B.1.0"))
+                    .put(RepositoryName.create("B"), RepositoryName.create("B.1.0"))
                     // mapping from @C to @C.2.0 is created despite not being mentioned
-                    .put(RepositoryName.create("@C"), RepositoryName.create("@C.2.0"))
+                    .put(RepositoryName.create("C"), RepositoryName.create("C.2.0"))
                     // mapping to @D is untouched because D has a multiple-version override
-                    .put(RepositoryName.create("@D_alias"), RepositoryName.create("@D"))
+                    .put(RepositoryName.create("D_alias"), RepositoryName.create("D"))
                     // mapping to @E is untouched because E is not a module
-                    .put(RepositoryName.create("@E_alias"), RepositoryName.create("@E"))
+                    .put(RepositoryName.create("E_alias"), RepositoryName.create("E"))
                     .build()));
   }
 
@@ -453,14 +453,14 @@
                 ImmutableMap.of(
                     RepositoryName.MAIN,
                     RepositoryName.MAIN,
-                    RepositoryName.create("@A"),
+                    RepositoryName.create("A"),
                     RepositoryName.MAIN,
-                    RepositoryName.create("@B"),
-                    RepositoryName.create("@B.1.0"),
-                    RepositoryName.create("@root"),
-                    RepositoryName.create("@root"),
-                    RepositoryName.create("@ws_repo"),
-                    RepositoryName.create("@ws_repo")),
+                    RepositoryName.create("B"),
+                    RepositoryName.create("B.1.0"),
+                    RepositoryName.create("root"),
+                    RepositoryName.create("root"),
+                    RepositoryName.create("ws_repo"),
+                    RepositoryName.create("ws_repo")),
                 RepositoryName.MAIN));
   }
 
@@ -488,10 +488,10 @@
                 ImmutableMap.of(
                     RepositoryName.MAIN,
                     RepositoryName.MAIN,
-                    RepositoryName.create("@A"),
+                    RepositoryName.create("A"),
                     RepositoryName.MAIN,
-                    RepositoryName.create("@B"),
-                    RepositoryName.create("@B.1.0")),
+                    RepositoryName.create("B"),
+                    RepositoryName.create("B.1.0")),
                 RepositoryName.MAIN));
   }
 
@@ -506,14 +506,14 @@
         "    path = '/a_remote_repo',",
         "    repo_mapping = {'x' : '@b'},",
         ")");
-    RepositoryName name = RepositoryName.create("@a_remote_repo");
+    RepositoryName name = RepositoryName.create("a_remote_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
 
     assertThatEvaluationResult(eval(skyKey))
         .hasErrorEntryForKeyThat(skyKey)
         .hasExceptionThat()
         .isInstanceOf(NoSuchPackageException.class);
-    assertContainsEvent("invalid repository name 'x': workspace names must start with '@'");
+    assertContainsEvent("invalid repository name 'x': repo names must start with '@'");
   }
 
   @Test
@@ -525,7 +525,7 @@
         "    path = '/a_remote_repo',",
         "    repo_mapping = {},",
         ")");
-    RepositoryName name = RepositoryName.create("@a_remote_repo");
+    RepositoryName name = RepositoryName.create("a_remote_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
 
     assertThatEvaluationResult(eval(skyKey))
@@ -533,7 +533,7 @@
         .isEqualTo(
             withMappingAllowingFallback(
                 ImmutableMap.of(
-                    RepositoryName.createFromValidStrippedName(TestConstants.WORKSPACE_NAME),
+                    RepositoryName.createUnvalidated(TestConstants.WORKSPACE_NAME),
                     RepositoryName.MAIN)));
   }
 
@@ -546,14 +546,14 @@
         "    name = 'a_remote_repo',",
         "    path = '/a_remote_repo',",
         ")");
-    RepositoryName name = RepositoryName.create("@a_remote_repo");
+    RepositoryName name = RepositoryName.create("a_remote_repo");
     SkyKey skyKey = RepositoryMappingValue.key(name);
 
     assertThatEvaluationResult(eval(skyKey))
         .hasEntryThat(skyKey)
         .isEqualTo(
             withMappingAllowingFallback(
-                ImmutableMap.of(RepositoryName.create("@good"), RepositoryName.MAIN)));
+                ImmutableMap.of(RepositoryName.create("good"), RepositoryName.MAIN)));
   }
 
   @Test
@@ -561,14 +561,14 @@
     new EqualsTester()
         .addEqualityGroup(
             withMappingAllowingFallback(
-                ImmutableMap.of(RepositoryName.create("@foo"), RepositoryName.create("@bar"))),
+                ImmutableMap.of(RepositoryName.create("foo"), RepositoryName.create("bar"))),
             withMappingAllowingFallback(
-                ImmutableMap.of(RepositoryName.create("@foo"), RepositoryName.create("@bar"))))
+                ImmutableMap.of(RepositoryName.create("foo"), RepositoryName.create("bar"))))
         .addEqualityGroup(
             withMappingAllowingFallback(
-                ImmutableMap.of(RepositoryName.create("@fizz"), RepositoryName.create("@buzz"))),
+                ImmutableMap.of(RepositoryName.create("fizz"), RepositoryName.create("buzz"))),
             withMappingAllowingFallback(
-                ImmutableMap.of(RepositoryName.create("@fizz"), RepositoryName.create("@buzz"))))
+                ImmutableMap.of(RepositoryName.create("fizz"), RepositoryName.create("buzz"))))
         .testEquals();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
index 217fbdd..ae1d3d6 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java
@@ -178,12 +178,12 @@
             "local_repository(name = 'a', path = '../a', repo_mapping = {'@x' : '@y'})",
             "load('//:b.bzl', 'b')",
             "local_repository(name = 'b', path = '../b', repo_mapping = {'@x' : '@y'})");
-    RepositoryName a = RepositoryName.create("@a");
-    RepositoryName b = RepositoryName.create("@b");
-    RepositoryName x = RepositoryName.create("@x");
-    RepositoryName y = RepositoryName.create("@y");
-    RepositoryName good = RepositoryName.create("@good");
-    RepositoryName main = RepositoryName.create("@");
+    RepositoryName a = RepositoryName.create("a");
+    RepositoryName b = RepositoryName.create("b");
+    RepositoryName x = RepositoryName.create("x");
+    RepositoryName y = RepositoryName.create("y");
+    RepositoryName good = RepositoryName.create("good");
+    RepositoryName main = RepositoryName.create("");
 
     SkyKey key0 = WorkspaceFileValue.key(workspace, 0);
     EvaluationResult<WorkspaceFileValue> result0 = eval(key0);
@@ -205,9 +205,9 @@
       TestManagedDirectoriesListener listener = new TestManagedDirectoriesListener();
       ManagedDirectoriesKnowledgeImpl knowledge = new ManagedDirectoriesKnowledgeImpl(listener);
 
-      RepositoryName one = RepositoryName.create("@repo1");
-      RepositoryName two = RepositoryName.create("@repo2");
-      RepositoryName three = RepositoryName.create("@repo3");
+      RepositoryName one = RepositoryName.create("repo1");
+      RepositoryName two = RepositoryName.create("repo2");
+      RepositoryName three = RepositoryName.create("repo3");
 
       PathFragment pf1 = PathFragment.create("dir1");
       PathFragment pf2 = PathFragment.create("dir2");
@@ -316,9 +316,9 @@
     assertThat(managedDirectories).hasSize(3);
     assertThat(managedDirectories)
         .containsExactly(
-            PathFragment.create("dir1"), RepositoryName.create("@repo1"),
-            PathFragment.create("dir2"), RepositoryName.create("@repo1"),
-            PathFragment.create("dir3"), RepositoryName.create("@repo2"));
+            PathFragment.create("dir1"), RepositoryName.create("repo1"),
+            PathFragment.create("dir2"), RepositoryName.create("repo1"),
+            PathFragment.create("dir3"), RepositoryName.create("repo2"));
     return workspaceFileValue;
   }
 
@@ -550,9 +550,9 @@
     SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
     EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
     WorkspaceFileValue value1 = result1.get(key1);
-    RepositoryName good = RepositoryName.create("@good");
-    RepositoryName main = RepositoryName.create("@");
-    RepositoryName secondary = RepositoryName.create("@secondary");
+    RepositoryName good = RepositoryName.create("good");
+    RepositoryName main = RepositoryName.create("");
+    RepositoryName secondary = RepositoryName.create("secondary");
     assertThat(value1.getRepositoryMapping()).containsEntry(secondary, ImmutableMap.of(good, main));
     assertNoEvents();
   }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java
index 73a3295..2236c29 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoaderTest.java
@@ -56,7 +56,7 @@
     embeddedBinaries.createDirectoryAndParents();
 
     mockEmbeddedTools(embeddedBinaries);
-    fetchExternalRepo(RepositoryName.create("@bazel_tools"));
+    fetchExternalRepo(RepositoryName.create("bazel_tools"));
   }
 
   private static void mockEmbeddedTools(Path embeddedBinaries) throws IOException {
@@ -135,7 +135,7 @@
     file("WORKSPACE", "local_repository(name = 'r', path='r')");
     file("r/WORKSPACE", "workspace(name = 'r')");
     file("r/good/BUILD", "sh_library(name = 'good')");
-    RepositoryName rRepoName = RepositoryName.create("@r");
+    RepositoryName rRepoName = RepositoryName.create("r");
     fetchExternalRepo(rRepoName);
 
     PackageIdentifier pkgId = PackageIdentifier.create(rRepoName, PathFragment.create("good"));
@@ -156,7 +156,7 @@
         "new_local_repository(name = 'r', path = '/r', "
             + "build_file_content = 'sh_library(name = \"good\")')");
     fs.getPath("/r").createDirectoryAndParents();
-    RepositoryName rRepoName = RepositoryName.create("@r");
+    RepositoryName rRepoName = RepositoryName.create("r");
     fetchExternalRepo(rRepoName);
 
     PackageIdentifier pkgId =
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/NoSuchPackageExceptionCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/NoSuchPackageExceptionCodecTest.java
index 05997dc..ad57d6e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/NoSuchPackageExceptionCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/NoSuchPackageExceptionCodecTest.java
@@ -34,23 +34,23 @@
   public void smoke() throws Exception {
     new SerializationTester(
             new BuildFileNotFoundException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")), "msg"),
+                PackageIdentifier.create("repo", PathFragment.create("foo")), "msg"),
             new BuildFileNotFoundException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")),
+                PackageIdentifier.create("repo", PathFragment.create("foo")),
                 "msg",
                 new IOException("bar")),
             new BuildFileContainsErrorsException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")), "msg"),
+                PackageIdentifier.create("repo", PathFragment.create("foo")), "msg"),
             new BuildFileContainsErrorsException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")),
+                PackageIdentifier.create("repo", PathFragment.create("foo")),
                 "msg",
                 new IOException("bar")),
             new InvalidPackageNameException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")), "msg"),
+                PackageIdentifier.create("repo", PathFragment.create("foo")), "msg"),
             new NoSuchPackageException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")), "msg"),
+                PackageIdentifier.create("repo", PathFragment.create("foo")), "msg"),
             new NoSuchPackageException(
-                PackageIdentifier.create("@repo", PathFragment.create("foo")),
+                PackageIdentifier.create("repo", PathFragment.create("foo")),
                 "msg",
                 new IOException("bar")))
         .setVerificationFunction(verifyDeserialization)
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PackageIdentifierCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PackageIdentifierCodecTest.java
index 72bf2fe..71e4e81 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PackageIdentifierCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PackageIdentifierCodecTest.java
@@ -27,7 +27,7 @@
 
   @Test
   public void testCodec() throws Exception {
-    new SerializationTester(PackageIdentifier.create("@foo", PathFragment.create("bar/baz")))
+    new SerializationTester(PackageIdentifier.create("foo", PathFragment.create("bar/baz")))
         .runTests();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
index 5617607..06588d6 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
@@ -26,8 +26,8 @@
   @Test
   public void testCodec() throws Exception {
     new SerializationTester(
-            RepositoryName.create(RepositoryName.MAIN.getNameWithAt()),
-            RepositoryName.create("@externalandshouldntexistinthisworkspace"))
+            RepositoryName.create(RepositoryName.MAIN.getName()),
+            RepositoryName.create("externalandshouldntexistinthisworkspace"))
         .runTests();
   }
 }
diff --git a/src/test/shell/bazel/local_repository_test.sh b/src/test/shell/bazel/local_repository_test.sh
index de2790b..0a1ce03 100755
--- a/src/test/shell/bazel/local_repository_test.sh
+++ b/src/test/shell/bazel/local_repository_test.sh
@@ -1047,7 +1047,7 @@
 EOF
 
   bazel build @r/a//:bin &> $TEST_log && fail "expected build failure, but succeeded"
-  expect_log "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'"
+  expect_log "repo names may contain only A-Z, a-z, 0-9, '-', '_' and '.'"
 }
 
 function test_remote_includes() {