web: rename a database from its settings page A database's name lives in two places — the metadata row and the on-disk store directory its path names — so a rename has to move both. The order is creation's: the row first, where a name already taken is refused by the unique index before anything on disk changes, then the store, then the handle the remotesapi memoized under the old path. A store that will not move rolls the row back, so the two halves never disagree about where a database lives; only a failed rollback is escalated to a human, because it is the one outcome no later request can repair. storage.MoveStore is one os.Rename behind the containment guard DeleteStore already used, extracted here as containedPath. It refuses an occupied destination outright: os.Rename over an empty directory would succeed and swallow it. No redirect is left behind — the old address simply stops resolving, as on git.sr.ht — so an existing clone needs its remote replaced, and a companion of a git repository is re-provisioned under its old name by the next push to that repository. The README's quickstart now says both.
storage: create databases empty so the first push needs no --force Every automatic creation path wrote an "Initialize data repository" commit through WriteEmptyRepo, and that commit is history. dolt decides fast-forward on the client (actions.CanFastForward over the remotesapi), so the server cannot forgive the collision: pushing a database that has a root commit of its own — a beads tracker, anything grown locally — was rejected as a non-fast-forward and could only land with --force. That is the whole reason the companion-database recipe starts with a forced push. push-to-create already provisioned an empty store for this exact reason. Give the other two paths the same default: /internal/repos, whose caller is git.sr.ht's post-update hook and therefore fires before its user has ever pushed, now always provisions empty, and the web form does unless its new "initialize with an empty commit" checkbox is ticked. The checkbox buys what an empty store cannot offer — a database that can be cloned before anything is pushed to it, since dolt refuses a store with no commits as "contains no Dolt data". Which is also why the overview of a database with no branches now teaches push rather than clone: the clone box there quoted a command that could not work. A store that fails to open is deliberately not treated as empty — an unreadable database must not be advertised as a fresh one.
feat(remoteapi): auto-create databases on first push to own namespace Push-to-create: an authenticated, non-suspended caller pushing (or cloning) an unknown repo under their OWN namespace has it transparently created — a PRIVATE repository row plus a genuinely empty on-disk NBS store — then proceeds through the normal ACL check as the owner. Any other case (anonymous, suspended, another user's namespace, invalid name) still returns NotFound, so a stranger's namespace is never leaked and nothing is created. storage.InitEmptyStore creates the store WITHOUT WriteEmptyRepo: an "Initialize data repository" commit would make the client's first push a non-fast-forward and be rejected. An empty store (root = empty hash) lets the initial push land as the repo's first history. The interceptor auto-create is race-safe (ErrNameTaken re-fetch) and rolls the row back if the store cannot be created. Proven end-to-end (integration): a real `dolt push` to a new name auto-creates PRIVATE + fast-forwards + re-clones; a foreign-namespace push is denied with no row created. All prior clone/push/ACL scenarios still pass.
rename module to sourcecraft.dev/bigbes/sr-ht-dolt; depend on sourcecraft sr-ht-core
storage: bare store init/delete and remotesrv DBCache InitStore writes a bare NBS store (LoadDoltDB Format_DOLT + WriteEmptyRepo) with partial-failure cleanup; DeleteStore guards against paths escaping the configured repos root; RepoDiskPath lays out <root>/~<owner>/<name>. Cache implements remotesrv.DBCache over an injected RepoLookup (no db import, no push-to-create): Get resolves via core.ParseRepoPath, memoizes one nbs.NewLocalStore per disk path, never creates directories; Evict/Close for delete and shutdown. Package doc records the LocalFilesysWithWorkingDir sealed-URL requirement proven by the Phase-0 spike. Unit tests cover store validity (reopen, main branch, initial commit), partial-failure cleanup, root-escape guard, and cache hit/miss/memoize/evict. Spike test untouched and still green.
foundation: module, core domain, schema, spike-verified dolt interop Phase 0 foundation for dolt.sr.ht (pure-Go Dolt hosting for SourceHut). Dependency pins: - core-go v0.0.0-20260520082310-fdb3662452dc: the production instance's submodule commit (fdb3662); must never be upgraded so token/config/crypto behavior matches the rest of the instance. - dolthub/dolt/go v0.40.5-0.20260626152440-45335d44ad79: pseudo-version at the commit tagged v2.1.10 (45335d44), matching the installed dolt CLI. The /go submodule's latest tag (v0.40.4, 2021) does not interop with a modern CLI; matching the CLI commit guarantees a common NBS format (Format_DOLT) and remotesapi proto. - gopkg.in/go-jose/go-jose.v2 v2.6.3: same JOSE version dolt's creds package signs EdDSA keypair JWTs with, avoiding a duplicate JOSE lib. - grpc v1.79.3, logrus v1.8.3, lib/pq v1.10.9, chi/v5 v5.3.1, brant v0.5.1. Contents: - core/ pure domain: models, ValidateName/ParseRepoPath, the access matrix (Allowed + NotFoundForPrivate), full table-driven tests. - schema.sql + migrations/0001_initial.sql (brant format). - config.example.ini, contrib/dolt.sr.ht.conf (nginx), Makefile, scss/main.scss, static/logo.svg, README, .gitignore. - internal/smoke: throwaway import-and-build check (deleted in Phase 3). Spike (storage/spike_test.go, tag `spike`): bare NBS store via WriteEmptyRepo, served by remotesrv on an ephemeral single port, round-tripped through the real dolt CLI v2.1.10 (clone -> insert -> commit -> push -> re-clone -> verify rows). Green, no version juggling needed beyond selecting the v2.1.10 commit. FS must be rooted at the repos dir (LocalFilesysWithWorkingDir) so sealed chunk-URL prefixes are clean relatives. Build note: dolt pulls go-icu-regex (CGO), which needs ICU4C headers; on this Mac set CGO_CPPFLAGS/CGO_LDFLAGS to icu4c@78 (documented in README).