First of all, please note that you can use the --dry-run option to the restic forget command to test forget policies without actually forgetting any snapshots. This is probably a good idea to do now that you’re trying to establish your policies and thereby the corresponding commands to use.
So, if you want to apply different policies to different tags, you probably need to use the --tag option with the tag you want to apply a policy to, so that you only apply the policy and forget snapshots that has this tag on them. Then you’d run one forget command for each tag.
Once you have that baseline, it should just be a matter of adding the proper --keep-* options for each of the tags you want. E.g. to keep a snapshot every four weeks back you add the --keep-weekly 4 option, to keep a snapshot every month for two months back add --keep-monthly 3, and so on. The --dry-run will let you see which snapshots restic would forget and which ones it would keep. Just try it and see
So in summary, for each of your repositories, you would run one forget command (with appropriate options) for each of the tags. So that would be 2 (repositories) * 4 (tags) = 8 forget commands. Note that after that you only need to run one prune command per repository though.
There is no option to avoid reencryption. However, most somewhat modern CPUs have hardware acceleration for AES which means that restic would be able to reencrypt a few gigabytes per second. Thus this is not a bottleneck.
restic copy will only copy snapshots and data chunks which are not present in the destination repository
Running copy after each backup run should work well. If the last few snapshots are identical, than copy will just copy the snapshot but nothing else.
copy adds a mark to snapshots when copying them, which allows it to recognize the already copied snapshots in later runs. It will have to read each file in the snapshots folder of the repository once to do that, but that should be reasonably fast, especially when cached. For the data chunks in the repository, restic uses an index which lists which chunks exist in a repository. Then copy just has to check whether a chunk exists in the target repository and copy it if it’s not the case.
The mark is part of the snapshot created in the destination repository.
restic by default caches the index and some other metadata for a repository. The checks which data has to be copied is done solely based on that metadata. That is with an enabled cache restic should most of the time be able to avoid downloading data from the destination repository. (It will have to download a few small files, but not much).