anchor.diff:  -spec resolve_symlink(file_ctx:ctx(), ctx()) -> {file_ctx:ctx(), ctx()} | no_return().
   resolve_symlink(SymlinkFileCtx, #resolution_ctx{
       user_ctx = UserCtx,
  -    space_id = SpaceId
  +    space_id = SpaceId,
  +    symlinks_encountered = PrevSymlinksEncountered
   } = ResolutionCtx) ->
  +    SymlinksEncountered = 1 + PrevSymlinksEncountered,
  +    NewResolutionCtx = case SymlinksEncountered > ?SYMLINK_HOPS_LIMIT of
  +        true -> throw(?ELOOP);
  +        false -> ResolutionCtx#resolution_ctx{symlinks_encountered = SymlinksEncountered}
  +    end,
  +
       SpaceIdSize = byte_size(SpaceId),
  -    NewResolutionCtx = assert_hops_limit_not_reached(SymlinkFileCtx, ResolutionCtx),
   
       case filepath_utils:split(read_symlink(UserCtx, SymlinkFileCtx)) of
           [] ->
  
positive.code: -record(resolution_ctx, {
      user_ctx :: user_ctx:ctx(),
      space_id :: od_space:id(),
      symlinks_encountered :: ordsets:ordset(file_id:file_guid())
  }).
  -type ctx() :: #resolution_ctx{}.
  
  
negative.code:     ResolutionCtx = #resolution_ctx{
          user_ctx = UserCtx,
          space_id = file_ctx:get_space_id_const(SymlinkFileCtx),
          symlinks_encountered = 0
      },
  
      {TargetFileCtx, _} = resolve_symlink(SymlinkFileCtx, ResolutionCtx),
  