// Command claims-migrate is the one-off conversion of a meta-core v1.2.0 store // (one kv table, schema version 2) into a v2.0.0 truth database (the claims // model, schema version 3) โ€” docs/implementation/metacore-claims-model.md ยง11. // It is run once by hand on watch.nsl.sh with meta-core stopped, and deleted // afterwards; nothing in the build references it. // // claims-migrate -old /meta-core/db/meta-core.db -truth /out/meta-core.db \ // -accounts /meta-core/identity/accounts [-dry-run] // // What it does: // - generates a throwaway "legacy" secp256k1 key in memory (its uid is // printed; the private key is never written anywhere); // - every record (rid) with at least one cid: each file:/ becomes // a claim on the record's canonical cid (internal/cid rank) signed by the // legacy key at one conversion ts; cids/ members become alias claims // (canonical, cids/) = "true"; filePath / mtimeNano (watcher facts, // refilled into local_file) and keys meta-core refuses (cid_*, midhash256, // canonical_cid, __fields__) are skipped; records with no cid are dropped; // - cid_group from the cid: โ†’ rid index (rids keep their UUIDs); // - UDL cells (MMUR1 records, signature checked) become MMUR2 claims signed // by the account key found in -accounts; rating โ†’ userRating; private-tier // envelopes are decrypted (AAD bound to the old version) and re-encrypted // with a fresh nonce and the MMUR2 AAD (bound to ts); cells whose account is // not on the box are dropped; // - btmagnet:* / searchcov:* / other service scratch keys are dropped (they // live in the cache now and are refetched); derived bookkeeping is skipped. // // Every claim is checked with claim.Verify before it is stored. The output is // created with meta-core's own storage code, so the truth schema cannot drift; // meta-core rebuilds the cache from it on first boot. package main import ( "flag" "fmt" "os" "runtime" ) func main() { var o options flag.StringVar(&o.oldPath, "old", "", "path to the v1 meta-core.db (opened read-only; copy it with its -wal/-shm first)") flag.StringVar(&o.truthPath, "truth", "", "output truth database path (must not exist)") flag.StringVar(&o.accountsDir, "accounts", "", "identity accounts dir ({META_CORE_PATH}/identity/accounts); empty = drop every UDL cell") flag.BoolVar(&o.dryRun, "dry-run", false, "convert, sign and verify everything but write nothing; print counts") flag.IntVar(&o.workers, "workers", runtime.NumCPU(), "signing goroutines") flag.Parse() if o.oldPath == "" || (o.truthPath == "" && !o.dryRun) { fmt.Fprintln(os.Stderr, "usage: claims-migrate -old -truth [-accounts ] [-dry-run]") flag.PrintDefaults() os.Exit(2) } if o.accountsDir != "" { if fi, err := os.Stat(o.accountsDir); err != nil || !fi.IsDir() { fmt.Fprintf(os.Stderr, "accounts dir %s is not a directory\n", o.accountsDir) os.Exit(2) } } else { fmt.Fprintln(os.Stderr, "warning: no -accounts: every UDL cell will be dropped") } o.log = os.Stderr st, err := migrate(o) if err != nil { fmt.Fprintf(os.Stderr, "claims-migrate: %v\n", err) os.Exit(1) } printSummary(os.Stdout, st, o.dryRun) if !o.dryRun { fmt.Printf("\ntruth database written: %s\n", o.truthPath) } }