v2.0.0: claims model - signed MMUR2 votes in a truth DB, merged view in a rebuildable cache DB; POST /api/claims, claims and merge routes, unsigned writes answer 410
Build and Push Docker Image / build (push) Successful in 5m1s

This commit is contained in:
Worph
2026-10-25 17:36:00 +00:00
parent b0adefb97b
commit 84af298792
78 changed files with 7203 additions and 5617 deletions
+71
View File
@@ -0,0 +1,71 @@
// 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:<rid>/<field> becomes
// a claim on the record's canonical cid (internal/cid rank) signed by the
// legacy key at one conversion ts; cids/<other> members become alias claims
// (canonical, cids/<other>) = "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:<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 <v1 meta-core.db> -truth <new truth db> [-accounts <dir>] [-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)
}
}