See the `cats` and `levels` methods. They are used to have rasters that behave like "factors".  The issues you describe have been fixed in terra 1.1-17 (on its way to CRAN). For now, what you can do is something along these lines:

    library(raster)
    f <- "nlcd_agg.grd"
    r <- raster(f)
    
    library(terra)
    x <- rast(r)
    
    # get the attributes
    lev <- levels(r)[[1]]  
    lev <- lev[, c("ID", "Land.Cover.Class")]
    lev[,2] <- as.character(lev[,2])

    x <- rast(r)
    levels(x) <- lev
    is.factor(x)
    #[1] TRUE
 
    x
    #class       : SpatRaster 
    #dimensions  : 101, 121, 1  (nrow, ncol, nlyr)
    #resolution  : 3750, 3750  (x, y)
    #extent      : 1394535, 1848285, 1722765, 2101515  (xmin, xmax, ymin, ymax)
    #coord. ref. : +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
    #source      : memory 
    #name        : nlcd_2011_landcover_2011_edition_2014_03_31 
    #min value   :                                Unclassified 
    #max value   :                                             

    # legend shows class names    
    plot(x)

Labels are returned as cell values

    x[c(7357, 5047, 7360, 9307)]
    #  nlcd_2011_landcover_2011_edition_2014_03_31
    #1                          Perennial Snow/Ice
    #2                                  Open Water
    #3                          Perennial Snow/Ice
    #4                                Unclassified

And the categories are stored if you save the raster to a GeoTIFF 

    z <- writeRaster(x, "test.tif", overwrite=TRUE)
    z

ch