Here's something that should work ok. I've based it off the standard "local delivery" router/transports, but added in conditions on the X-Spam-Flag header, which I'm setting earlier in the relevant ACL. If you don't know how to do that, let me know and I'll amend the answer.
I do something similar, but at a domain level, and my setup probably won't work too well for you.
First of all, you need a router. Routers are processed in order, so put this somewhere suitable - generally before you catch normal mail, because that will take precedence.
spamcheck:
debug_print = "R: spamcheck for $local_part@$domain"
driver = accept
check_local_user
user = mail
condition = "${if def:h_X-Spam-Flag: {yes}{no}}"
transport = local_spam_delivery
Now you need a local_spam_delivery transport, so put this anywhere in your transports section:
local_spam_delivery:
debug_print = "T: local_spam_delivery for $local_part@$domain"
driver = appendfile
directory = /home/mail/$domain/$local_part/spam/
maildir_format
delivery_date_add
envelope_to_add
return_path_add
If you don't want it as a maildir, remove the maildir_format command. You may have to tweak the rules a bit, especially regarding user and group settings etc.
If there is something missing in my above example, I notice there's a similar example documented here