Add hidden `doctor migrate-to-ulid` validation tooling (branch+hex → refs+ULID) · Entire
Add hidden doctor migrate-to-ulid validation tooling (branch+hex → refs+ULID)
2dc8888· Soph·1w ago·5 files·+689 added/-0 removed
Test tooling to convert a THROWAWAY COPY of a git-branch + hex-id repo into one that reads as if it had used git-refs + ULIDs from the start, so we can stage a realistic validation repo and exercise commands + the UI against it.
What it does (dry-run preview by default; --yes to apply):
- Re-identifies every checkpoint on entire/checkpoints/v1 as a fresh ULID (minted from the checkpoint's original CreatedAt, so ULIDs sort by real time), stored under refs/entire/checkpoints/
/ . The embedded checkpoint_id in the root + per-session metadata.json is re-stamped to the ULID; everything else (transcripts, summaries, attribution) is carried over byte-for-byte. No commit SHAs are embedded in checkpoint content, so the later history rewrite doesn't stale it. - Rewrites the Entire-Checkpoint commit trailers hex → ULID across all local branches except entire/* (git filter-branch --msg-filter; rewrites history).
- Deletes the entire/checkpoints/v1 branch and the shadow branches so only the ULID refs remain — refs-native.
The migrated checkpoints resolve through the normal read path (kind routing → refs) and are enqueued for push like any git-refs write.
Kept hidden and, per intent, on this branch (not for merge to main) — it rewrites history irreversibly apart from git's refs/original backup.
Tests: core re-ID/re-stamp/dry-run/no-branch + ULID-timestamp minting, and an end-to-end command test (real commit trailers → ULID, v1 deleted, checkpoint resolves via Open().Persistent).
Sessions
904b45068824View transcript
Changes
5
- cmd/entire/cli
- checkpoint
- Amigrate_ulid.go +211
- Amigrate_ulid_test.go +128
- Mdoctor.go +1
- Adoctor_migrate_ulid.go +233
- Adoctor_migrate_ulid_test.go +116
- checkpoint
package checkpoint
import (
"context"
"crypto/rand"
"encoding/json"
"errors"
"fmt"
"log/slog"
"strconv"
"time"
git "github.com/go-git/go-git/v6"
"github.com/go-git/go-git/v6/plumbing"
"github.com/go-git/go-git/v6/plumbing/filemode"
"github.com/go-git/go-git/v6/plumbing/object"
ulidpkg "github.com/oklog/ulid/v2"
"github.com/entireio/cli/cmd/entire/cli/checkpoint/id"
"github.com/entireio/cli/cmd/entire/cli/logging"
"github.com/entireio/cli/cmd/entire/cli/paths"
)
// ULIDMapping records one legacy-hex checkpoint re-identified as a ULID.
type ULIDMapping struct {
OldID id.CheckpointID // legacy 12-hex id (on the v1 branch)
NewID id.CheckpointID // freshly minted ULID (now a per-checkpoint ref)
}
// ULIDMigrateResult summarizes a hex → ULID checkpoint migration.
type ULIDMigrateResult struct {
// Total is the number of checkpoints found on the v1 branch.
Total int
// Mapping lists each re-identified checkpoint, in walk order. Callers use it
// to rewrite the Entire-Checkpoint commit trailers from hex to ULID.
Mapping []ULIDMapping
// Skipped counts checkpoints left as-is because their id is already a ULID.
Skipped int
}
// MigrateBranchHexToULIDRefs re-identifies every legacy-hex checkpoint on the
// git-branch v1 branch (entire/checkpoints/v1) as a fresh ULID stored under a
// per-checkpoint ref (refs/entire/checkpoints/<shard>/<ulid>), ...
func MigrateBranchHexToULIDRefs(ctx context.Context, repo *git.Repository, dryRun bool) (ULIDMigrateResult, error) {
var result ULIDMigrateResult
branch := NewGitStore(repo, DefaultV1Refs())
tree, err := branch.getSessionsBranchTree()
// ... omitted for brevity
}
// mintULIDAt mints a canonical ULID checkpoint id whose timestamp is t (falling
// back to now when t is zero), ...
func mintULIDAt(t time.Time) (id.CheckpointID, error) {
// ... omitted for brevity
}
// restampCheckpointID rewrites the embedded checkpoint_id (hex → newID) in the
// checkpoint's metadata.json files ...
func restampCheckpointID(repo *git.Repository, cpTreeHash plumbing.Hash, newID id.CheckpointID, sessionCount int) (plumbing.Hash, error) {
// ... omitted for brevity
}
Here is where more information about implementation details would go.