Here is a way using MapIndexed
:
ds[MapIndexed[<| #, "intervals" -> intervals[[#2[[1]]]]|> &]]

Streams
In some other software environments, streams are often used to solve problems like this. For lists, we can define a poor-man's version like this:
stream[list_List] := Module[{i = 1}, If[i > Length[list], Missing[], list[[i++]]] &]
Then we can write:
nextInterval = intervals // stream;
ds[All, <| #, "interval" -> nextInterval[] |> &]

Streams can greatly simplify merging operations. Let's say we wanted to add each interval as two columns instead of one:
nextLimit = intervals // Flatten // stream;
ds[All, <| #, "lower" -> nextLimit[], "upper" -> nextLimit[] |> &]

Or perhaps we wanted to add columns from multiple sources:
nextInterval = intervals // stream;
nextCode = "ROYG" // Characters // stream;
nextColor = {Red, Orange, Yellow, Green} // stream;
ds[All, <| #, "interval"->nextInterval[], "code"->nextCode[], "color"->nextColor[] |>&]

Coming Soon?
Since at least version 10.4 of Mathematica there has been an undocumented set of iterator functions. Perhaps they will become documented some day? Then we could officially write:
nextInterval = GeneralUtilities`ToIterator[intervals];
ds[All, <| #, "interval" -> Read[nextInterval] |> &]

Also in the Coming Soon? department, we have the Streaming package of Leonid Shifrin.
dataset[All, <|#, "intervals" -> intervals|> &]
I'm adding the whole list to the column at every row, I need to somehow dointervals[i]
, if you know what I mean. $\endgroup$