Dictionary Validation

This is also probably not complete. More questions incoming...
Looking at this: https://github.com/ambiata/ivory/blob/topic/dictionary-validation/ivory-ingest/src/main/scala/com/ambiata/ivory/ingest/DictionaryImporter.scala#L27-L28 it seems like the return type may be ok in the long term, because we will be potentially adding _hard_ failures as well. For example:
 - Changing an encoding results in a stern warning that may be overriden by `--force`.
 - Having two attributes in the dictionary that must be consistent (when we add stronger validations, a validation and an encoding might be inconsistent, i.e. having a numerical validation attached to something encoded as a string would always want to fail regardless of  `--force`).

So something like this in very rough psuedo code:

```
validate(oldDictionary, newDictionary) match {
  case Failure(errors) => 
    val (soft, hard) = errors.partiton(isWarning(force))
    soft.traverseU(print) >> hard.traverseU(print) >> Result.fail(...).when(!hard.isEmpty)
  case s @ Success(_) => 
    s.pure[ResultTIO]
}
```
(note this is the same as `validation.swap.flatMap` but because of validations horrendous naming it makes it really hard to follow/read IMO).