separate clockspec parsing from evaluation

Summary:
The semantics of clockspec parsing are currently unclear. Passing in the root is optional, and it might or might not lock the root. Upcoming patches will make evaluation even
trickier. To fix this:

- split it up into parsing and evaluation steps. Parsing is done independent of any root, and evaluation is only done while the root is locked.
- insert calls to the appropriate function in each appropriate place.
- make a few assumptions explicit via the struct definition, e.g. that timestamps cannot be fresh instances.

Test Plan: `arc unit --everything`

Reviewers: wez

Reviewed By: wez

Differential Revision: https://phabricator.fb.com/D913912

Task ID: 2689998

--HG--
extra : rebase_source : 967303fa8ae4d8eb1db75a400711789665d188fa
extra : amend_source : 801ce4e48f89f44f846605ea6532caaed8638728