Snapshot metadata

This isnt for merging yet, just WIP,

Bit of a slow start, but figured while I am still finding my way around the codebase i'll raise this so ppl can peek at the progress more conveniently and give me feedback as i go.
If we are going to do lots of these (assuming that we will), might be worth adding this little thing somewhere:
```
  def encodedecode[A: EncodeJson: DecodeJson: Arbitrary: Equal] =
    forAll(CodecJson.derived[A].codecLaw.encodedecode(_))
```

Makes this just an inline ${encodedecode[CommitId]} and delete the test impl together.