Excellent ideas all around, I'd personally add some new tags that reflect some of your new concepts rather then incorporating them in the current tags.
I'd do this with a [CATALYST] tag which appears in place of [REAGENT] and is like it in every other way, the Catalyst is needed to complete the reaction but is not altered or consumed as you stated, this avoids adding additional booleans to reagents which could possibly trip you up when editing the raws when you confuse it with the quantity value. I see uses for this outside of just contains.
Yeah, that approach does make a lot more sense -- more clarity and less clutter in the syntax. Although I might use NEUTRAL instead of CATALYST, just in case people haven't taken chemistry.
I'd use a new tag for that as well [PRODUCT_CONTAINER:container type:ID for which product goes here], this would make it clear that the container is not a 'real' reagent and you would only have to specify the container once rather then something like [REAGENT: empty container] [PRODUCT: container full of actual product] which is more entries and more error prone. The correct number of empty container are automatically brought to the workshop based on the maximum amount of product that could be created and the size of the containers. In addition it would allow for 'smart' behavior like automatically using any container that reagents came in to count towards the needed product containers if their compatible.
For example, converting Strawberry wine to Strawberry vinegar would have the wine as the reagent and the vinegar as the product and if I specify Barrel as the Product container then the AI will recognize that the barrel the wine comes in is usable for the vinegar and no extra barrel fetching is needed. But say I wanted to bottle the vinegar I could put bottles as the container and this would require that an appropriate number of bottles be fetched and used for the product. Allowing the game to determine how many of the specified product containers are necessary on the fly will avoid impossible to fulfill 'cramming' or loss of products or excessive containers being used if someone miscalculates the number of necessary containers.
Just to be clear -- in this approach, an additional PRODUCT_CONTAINER tag would be needed for each product that gets placed in a container? Hmm, that could mean a lot of tags, and it wouldn't let you specify that two items should be placed in the same container (probably okay for fluids, but not for items in bins). It also doesn't allow you to use one of the products as a container for another product, as in my craft-in-bin example. You are right, though, that the containers don't need full REAGENT or CATALYST syntax -- the material doesn't matter, all you need is the container type.
Doing things "on the fly," while definitely the most flexible approach, might require changes to the entire job system -- I'm not sure the game currently allows the dependence of one job item on another (i.e. you may need one barrel or two depending on how many strawberries you're brewing) -- and I'm trying to stick to relatively easy-to-implement stuff. (lol)
Maybe you could just have a [CONTAINER:id_string_for_this_container:BIN] type thing, and then every product would specify either a container, another product to use as a container, or nothing. This gives the benefits you mentioned of a) making containers distinct from real reagents and catalysts and b) leaving the container material open-ended, while also giving you more control over how products get placed in containers.