Add `TrackedSymbols :> {c}`
y[x_, c_] := -x^2 + c
Manipulate[
Grid[{
{ymax = FindMaximum[{y[x, c], -1 <= x <= 1}, x]},
{Plot[y[x, c], {x, -1, 1}]}}
],
{c, -0.5, 0.5},
TrackedSymbols :> {c}
]
Now

Manipulate by default will track all symbols that shows inside it. So when you typed `ymax`, frontend tracked this symbols and Manipulate went and re-evaulated its expression again, and that is why you got `0.5`.
As a rule of thumb, I always use `TrackedSymbols`. This keep things safe. Also use a `Module` inside `Manipulate` for more robust code. Like this:
Manipulate[
Module[{ymax,x},
Grid[{
{ymax=FindMaximum[{y[x,c],-1<=x<=1},x]},
{Plot[y[x,c],{x,-1,1}]}}
]
],
{c,-0.5,0.5}
]
And now you do not even need `TrackedSymbols`, but I would still use `TrackedSymbols`.
So rules of thumbs
1. Use Module inside Manipulate to hide any non-control variables used inside Manipulate. (in your example, these would be `x` and `ymax`.
2. Use `TrackedSymbols` to explicitly list the symbols being tracked. In your case `c`.
This should eliminate most of the problems.