Updating vibe-qc

For an existing checkout you’ve already used. If this is your first install, see installation instead.

The easy button

./scripts/update.sh

That command pulls the latest tagged release, rebuilds any native dependencies whose source changed, refreshes the Python package inside your .venv/, and prints the new banner so you can confirm the version flipped. About 30 seconds wall-time on a vanilla git pull (no native-dep changes); 5–15 minutes if a vendored library version bumped between releases.

After the script finishes you should see a banner like:

╔════════════════════════════════════════════════════════════════════════╗
║ Release v0.4.2  —  Quantum chemistry for molecules and solids          ║
║ © Michael F. Peintinger · MPL 2.0  ·  https://vibe-qc.com              ║
║ linked: libint 2.13.1 · libxc 7.0.0 · spglib 2.7.0                     ║
╚════════════════════════════════════════════════════════════════════════╝

The first line tells you which release you’re on. If it shows the old version you didn’t expect, see common issues below.

Variants

./scripts/update.sh --ref main          # bleeding-edge dev (X.Y.dev0 banner)
./scripts/update.sh --ref v0.4.2        # pin to a specific tag
./scripts/update.sh --rebuild-native-deps   # see "Vendored library version bumps" below

--ref accepts any branch or tag name. The default (release) is the right choice for the vast majority of users — it tracks whatever the project author has tagged as the current public release.

-h / --help prints the same option list inline.

Manual equivalent

If you’d rather invoke the steps by hand (e.g. when debugging an update that didn’t take), here’s what update.sh does:

# 1. Refuse if working tree is dirty (silently stashing user work
#    is worse than failing loud)
git diff --quiet && git diff --cached --quiet || \
    { echo "uncommitted changes — commit or stash"; exit 1; }

# 2. Fetch and check out the target ref (release branch by default)
git fetch origin --tags
git checkout release
git pull --ff-only origin release        # only on branches; tags don't pull

# 3. Rebuild any native deps whose source changed
./scripts/setup_native_deps.sh

# 4. Refresh the Python package (rebuilds the C++ extension)
.venv/bin/pip install -e '.[test]'

# 5. Confirm the new banner
.venv/bin/python -c "import vibeqc; vibeqc.print_banner()"

Step 3 is the heavy one if anything changed. Each build_*.sh skips work when its install/ tree already exists, so a vanilla pull usually takes seconds.

Switching between releases

Sometimes you want to drop to a previous release temporarily — to reproduce an old result, or to confirm a regression bisects to a specific tag.

./scripts/update.sh --ref v0.4.0
# ... run the calculation, compare ...
./scripts/update.sh --ref release         # back to current

The on-disk state is fully consistent at each step. Outputs from your previous calculations survive — only the vibe-qc code changes.

Going to bleeding-edge main

./scripts/update.sh --ref main

main is where active development lands. Banner reads dev X.Y.devN (main @ <sha>) — the SHA pins the build for reproducibility. Use this when you need a feature that’s already merged but not yet released; don’t use this for publication-quality numbers (subtle bugs may be undetected until the next regression-test pass).

To go back to the published release:

./scripts/update.sh --ref release

Common issues

Vendored library version bumps

setup_native_deps.sh’s per-dep idempotency check looks at “does third_party/<dep>/install/lib/cmake/X/XConfig.cmake exist?” — and skips if yes. If a release bumps libxc 7.0.0 → 7.0.1 (or libint / spglib / FFTW / libecpint), the user’s stale install silently sticks around and pip install links against it.

Diagnostic: after running ./scripts/update.sh, the banner’s linked: libint X.Y.Z · libxc A.B.C ... line should match the versions pinned in the various scripts/build_<dep>.sh. If it doesn’t, the stale-install case has bitten.

Fix:

./scripts/update.sh --rebuild-native-deps

That nukes every third_party/<dep>/install/ tree before re-running the native-deps orchestrator, forcing each dep to rebuild from source against its currently-pinned version.

OSError: cannot load library 'libxc.so.7'

A vendored dep’s install/ tree was wiped (or never built). Re-run:

./scripts/update.sh --rebuild-native-deps

CMake complains about a stale build cache after update

Rare but possible if scikit-build-core’s build cache went stale:

rm -rf build/ .scikit-build*
.venv/bin/pip install -e '.[test]' --force-reinstall --no-deps

Tests fail after update

.venv/bin/python -m pytest tests/

If a few tests fail right after a major update, that’s a real signal worth investigating — please open an issue with the banner output and the pytest tail. Don’t ignore the failures and run “real” calculations on the build until the regression is understood.

Long-running calculations across an update

If you have a long calculation in flight and want to update vibe-qc without disturbing it, don’t: in-flight python processes hold references to the loaded _vibeqc_core.so, so an update mid-flight doesn’t break the running job, but starting a new calculation in the same shell will pick up the new code immediately. Cleanest is:

  1. Wait for the running job to finish (or pause it via Ctrl-Z and bg if you must).

  2. Update.

  3. Start subsequent jobs.

For background-run patterns (tmux + tee), see the running guide.

Where to go next

  • Quickstart — confirm the new install with a smoke-test calculation.

  • Release process — the upstream side of the release flow that drives what you’re updating to.

  • Changelog — what shipped in the release you just installed.