The behaviour we see here is due to Set performing limited evaluation of its left-hand-side prior to the assignment.
Set Evaluates the Left-Hand-Side
Despite the fact that Set has the attribute HoldFirst, it performs a special kind of evaluation upon its left-hand-side prior to performing the assignment. Specifically, if the left-hand-side has a head and parts, then that head and those parts are evaluated -- but no further rules are applied to the result.
Here is a generic example illustrating this behaviour:
ClearAll[f1, f2, a1, a2]
f1 = f2;
f2[___] := Print@"f2 evaluated!"
a1 = 1; a2 = 2;
f1[a1 + a2] = 999;
??f2

Observe how even though the Set expression was assigning to f1[a1 + a2], the resulting definition is actually attached to f2[3]. f1 was evaluated to f2 and a1 + a2 was evaluated to 3. But also note that the pre-existing definition that matches f2[3] was not invoked, and nothing was printed.
In contrast, if the left-hand-side has no parts, it is not evaluated:
ClearAll[a, b]
a = b;
a = 3;
??a

??b

The Case At Hand
Let us now apply this knowledge to the case at hand.
For (a @@ index) = 5, Set performs the limited evaluation upon the left-hand-side. index is replaced with {3, 4} to produce a @@ {3, 4} which is to say Apply[a, {3, 4}]. As noted above, the normal definition of Apply is not expanded so this is the final left-hand-side. Next, Set attempts to assign 5 to this expression. Since Apply is protected, the attempt fails with an error message.
Now, a[Sequence @@ index] = 5. By construction, the head a is inert so it evaluates to itself. Sequence @@ index is evaluated to produce Sequence[3, 4]. Since a does not have the SequenceHold attribute, the Sequence head is stripped yielding a final left-hand-side of a[3, 4]. This is a valid and unprotected assignment target, so the assignment succeeds.
Why Does Set Behave Like This?
It is necessary for Set to perform at least some evaluation of the left-hand-side for otherwise expressions like x[i, j-1] = y would be far less useful. We want to have the indices i and j-1 evaluated. On the other hand, full evaluation of the left-hand-side would mean that we could never reassign a variable after its initial assignment because it would disappear from the left-hand-side by evaluation. Thus, we have these arcane rules of partial evaluation. Most of the time, these rules just "do the right thing". But occasionally, like for the present question, the subtleties of the rules are observable.
Workaround
One way to work-around the present problem is as follows:
(a[##] = 5) &@@ index
a @@ index
(* 5 *)
(a[##] = 6) &@@ index
a @@ index
(* 6 *)
The technique works even if a prior assignment has been performed.
Setholds its first argument, so you need to force the evaluation insideSet. To work in all cases (including the case whenahas been already defined on that index), I'd do something likeHold@@index/.Hold[inds__]:>Set[a[inds],5]. This seems to be a duplicate of at least one similar question, but I can't find it. – Leonid Shifrin Oct 13 '14 at 13:34