Recognize ULID checkpoint IDs alongside legacy hex
main·
Commit

The "understanding" layer for ULID checkpoint IDs: the id package now accepts, validates, and shards both the legacy 12-char lowercase hex format and 26-char Crockford base32 ULIDs. Purely additive — hex behavior is unchanged, and generation still emits hex (emitting ULIDs is a separate, store-coupled change).
- ULIDPattern + ulidRegex; Kind/KindOf + CheckpointID.Kind classify legacy/ULID/ unknown.
- ShardFor: first two chars for legacy (preserves the v1 tree layout), LAST two for ULID (leading chars are the timestamp and barely vary; the random suffix shards evenly while the ID stays lexicographically sortable).
- CheckpointPattern = (hex|ulid) for matching a checkpoint ID in free text (e.g. the Entire-Checkpoint trailer). Pattern stays 12-hex — it is reused for run IDs by investigate/provenance, which are not checkpoint IDs.
- Validate / NewCheckpointID / UnmarshalJSON accept either format (invalid only when KindOf == KindUnknown); empty-string handling unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com Entire-Checkpoint: ab5934c248d2
Checkpoints
Checkpoint 1