I am going to assume that you are initialising your $katfood & $inv story variables in one passage...
<<set $katfood = {
name: "Kat Food",
amount: 5
}>>
<<set $inv = [$katfood]>>
... and you have your loop & value changing code in another passage...
<<if visited() is 1>>
<<set $katfood.amount++>>
<</if>>
$katfood.amount /* this changed */
<<for _item range $inv>>
_item.name - _item.amount /* this does't change. */
<</for>>
... and that you want to know why changing the value of the amount property of object in the $katfood story variable doesn't effect the instance of the object within the $inv Array.
Each time the story transitions from one passage to another (can be the same passage) the current state (values) of all known variables is cloned. The original copy of the state is added to the History systems, and the cloned copy is made available to the passage that is about to be shown. This cloning process results in each object reference now referencing their own unique copies of the original objects.
eg. In your first example you had the $katfood story variable and the first element of the $inv Array both referencing the same object. After the passage transition $katfood would now reference one copy of the original object and the first element of the $inv Array would now references a different copy of the original object.
The way you get around this behaviour is to store a reference to either an index or a key within the Array, instead of an object reference.
1. Initialise a single instance object and store a copy of it's key with the $inv Array.
<<set $items = {
"kat-food": {
name: "Kat Food",
amount: 5
},
"dog-food": {
name: "Dog Food",
amount: 5
}
}>>
<<set $inv = ["kat-food"]>>
2. Use the "kat-food" key to reference the single instance of the associated object.
<<if visited() is 1>>
<<set $items["kat-food"].amount++>>
<</if>>
$items["kat-food"].amount /* this changed */
<<for _id range $inv>>
$items[_id].name - $items[_id].amount /* and so did this */
<</for>>