Project-level standing rules for Claude chats working on vibe-qc¶
This file is auto-injected for every Claude Code session in
this repository. It carries project-level discipline that
every contributor (human or AI) needs to follow. User-level
specifics (planetx access, per-laptop venv conventions,
no-SSH-to-bayes etc.) live in ~/.claude/projects/.../memory/
and are intentionally NOT here — those don’t generalise across
machines / contributors.
If you’re a Claude chat on this repo, read this whole file before your first edit. It’s short.
1. Licensing discipline (NON-NEGOTIABLE)¶
vibe-qc is MPL 2.0 and we ship to academic + open-source users. Getting licensing wrong has real consequences for the project.
Before bundling, vendoring, or fetching anything new:
Check the redistribution terms. Original publication’s license, BSE entry’s notes, third-party
LICENSE/COPYINGfiles. Don’t assume “open” means “redistributable”.If the terms are unclear or restrictive: don’t bundle. Use the on-demand fetcher pattern (modeled on
vqfetch): pull from source on first use, cache locally per XDG, surface per-record provenance + license string in the SCF log +.systemmanifest.For citation-required content (basis sets, ECPs, functionals): preserve the per-publication reference in file headers and ensure the citation is reachable from user-facing output.
The full per-component inventory is at
docs/license.md. When in doubt, expand
that page rather than silently shipping new bundled data.
Known caveats already documented:
FFTW3 is GPL v2. vibe-qc dynamic-links it for the FFT-Poisson solver. Combined binary is effectively GPL v2. Roadmap entry: FFT backend abstraction (
VIBEQC_FFT_BACKEND={fftw3,pocketfft,kissfft}) for commercial-friendly binaries.basissetdev’s 87 BSE-fetched basis sets are NOT shipped in v0.8.0 (see § 4 below). On-demand BSE fetcher is the intended architecture once basissetdev merges.
2. Branch model + push discipline¶
vibe-qc has two long-lived branches (docs/release_process.md):
main— active development. Every feature, fix, refactor lands here first. CI must pass. Daily commits expected. Maintainers + agents may push after CI green.release— public-facing. Fast-forward only, only from a tagged commit onmain.
Pushing from a Claude worktree:
The standard pattern is rebase-then-push:
git fetch origin --quiet git pull --rebase origin main git push origin HEAD:main
Other chats push to main in parallel; without rebase your push will be rejected.
Never
git push --forcetomainorrelease.Never
git commit --amendon a commit you’ve already pushed.Never skip pre-commit hooks (
--no-verify,--no-gpg-sign) unless the maintainer explicitly asks. If a hook fails, fix the underlying issue — don’t bypass.Tag commits are made by the release chat per
docs/release_process.md§ “Cutting a release”. Don’t tag from arbitrary chats.
Checking CI after a push (glab api):
On a machine with the glab CLI authenticated against
gitlab.peintinger.com (the maintainer’s machines are), chats
can query pipeline status directly:
# recent pipelines (status / sha / web_url)
glab api "projects/19/pipelines?per_page=5"
# jobs of one pipeline; trace of one job
glab api "projects/19/pipelines/<pipeline-id>/jobs"
glab api "projects/19/jobs/<job-id>/trace"
Use the numeric project id (19 = mpei/vibeqc). Path-based
lookups (glab ci list, -R mpei/vibeqc,
projects/mpei%2Fvibeqc) return 404 or the sign-in page on
this instance: the URL-encoded slash is decoded before it
reaches the API, so every glab ci convenience subcommand is
broken here. Stick to glab api with the id.
Main moves fast and GitLab auto-cancels pipelines superseded
by a newer push to the same ref. A canceled status on your
commit’s pipeline means replaced, not failed; what counts is
green on the current head pipeline, whose tree contains your
commit.
What a green pipeline means: the build-test job is a
build-break gate only (canonical bootstrap, import vibeqc,
pytest --collect-only; cache-warm runs take ~20 min). It
executes no tests. Full-suite verdicts come from
scripts/test_gate/ on a dev box, per § 14.
3. Multi-chat coordination — the drop-box convention¶
vibe-qc development is split across multiple parallel Claude chats (periodic SCF, molecular methods, basissetdev, vqfetch, docs, vq queue, …). Coordination happens through a structured status-file convention, not through ad-hoc inter-chat messaging.
Per release (v0.X.0), the release chat opens a directory
at .release-status/v0.X.0/. Each contributing dev chat
writes one status file: .release-status/v0.X.0/<chat-id>.md.
Drop-box files are gitignored, local-only, deleted post-tag
(Phase E of the release-chat runbook).
The drop-box file follows a fixed template:
Self-id, branch + tip SHA, last-verified-green-tests metadata.
Deliverables claimed in CHANGELOG
[Unreleased]— per-item: SHA, tests, open issues blocking tag.Tag-ready? YES/NO with the gating reason if NO.
Slips out of v0.X.0 — what moves to a later release.
Upstream dependencies on other dev chats.
Asks pending to other chats.
Anything not in CHANGELOG that should be.
Codename objection? (yes/no with reasoning).
The docs chat is the one consumer that needs drop-box
content to outlive the deletion — extract any quotes / numbers
/ SHAs into permanent docs (docs/release_v0_X_0_prep.md,
docs/license.md, user-guide pages) before Phase E runs.
4. The basissetdev standing rule¶
Mike’s standing rule (2026-05-07):
“All this shall be kept in a basissetdev branch that is always rebased on main when features land, but I shall not be merged into main before we are done. We want to write papers from that.”
Implications:
basissetdevdoes NOT merge intomainfor v0.8.0 (or v0.8.x). It stays a paper-writing branch.The Phase 14e
vq.auto_ecp_centers(...)auto-discovery helper and the 87 BSE-fetched basis sets are basissetdev-conditional — document them as such (seedocs/user_guide/ecp.md§ Phase-14e for the pattern).Shipped on
main(maintainer decision, 2026-06-21): the Phase 14f CRYSTALINPUT-format ECP-block parser (basis_crystal.pyCrystalECP) and the Phase 14g periodic ECP application (compute_ecp_lattice_from_primitivesplus the pob-TZVP-REV2 auto-attach inrun_periodic_job) are onmainas the maintainer-approved supported subset (option (a) ofHANDOVER_COHESIVE_ECP_APPLY.md). They are not basissetdev-conditional. An earlier revision of this rule listed the 14f parser as conditional, which was superseded when that subset landed.The basic ECP machinery (manual
ECPCenterrecipe via libecpint) is onmainand ships in v0.8.0. Don’t conflate “ECP support” with “basissetdev features”.
If a chat needs basissetdev features for its own work, rebase basissetdev on main and work from the basissetdev tip — but don’t propose merging basissetdev into main without explicit maintainer approval.
5. Documentation cadence — when to refresh what¶
Codified in
docs/release_process.md:
Per-tag mechanical sprint (~3 hours, every release) — copy-and-adapt the
docs/release_v0_8_0_prep.mdplaybook; pre-staged copy is the norm. CHANGELOG promotion, homepage admonition swap, roadmap “shipped” sweep, version bumps, banner refresh.Per-quarter deep audit (~6–8 hours) — tutorial parity re-walk (
docs/roadmap.md§ Tutorial parity), stale-link audit, stale-API audit,features.mdregen, user-guide coverage audit, cross-link audit.Lightweight ongoing (every session) — new bug → homepage admonition update same session; behaviour change → user- guide cross-reference same session. Don’t queue.
If you’re touching docs and not sure which cadence applies, default to “lightweight ongoing” — fix what you see while you’re there.
7. Periodic SCF oscillation = bug, not convergence problem¶
If a periodic SCF oscillates, lands at impossible energies (over-bound by Madelung-scale shifts, e.g. ~0.5 Ha on H₂/STO-3G in a 30-bohr box), or converges to a stationary point disagreeing with PySCF.pbc.GDF by more than µHa: that’s a bug, not a convergence aid problem.
Don’t paper over with:
Damping / level-shift / quadratic-fallback as primary fix.
Empirical
auto_optimize_truncationthresholds.Tightening DIIS until the oscillation hides.
Do:
Reproduce against PySCF.pbc.GDF on the same system.
Check the gauge / Madelung / image-summing carefully.
File a regression test capturing the symptom.
Bring it to the periodic-SCF chat or the regression-suite chat; don’t fix-then-forget.
The v0.7.0 Madelung self-image leak (over-bound by ~0.587 Ha on H₂/STO-3G in a 30-bohr box, fixed in Löwdin’s Compass) is the canonical example of why this discipline matters.
8. Citation discipline¶
For published work using vibe-qc, the citation surface is mandatory:
vibe-qc itself: per
CITATION.cff+ the JCC release paper once published.Basis sets used: per the
.g94file headers (preserved through the libint / BSE pipeline).ECPs used: per the libecpint per-element references.
Functionals used: libxc convention (Lehtola 2018 + per-functional originals; see
docs/user_guide/functionals.md§ Citations).External data fetched via vqfetch: per the per-record
Provenancebundle (source DB + DOI + license carried through to the SCF log).
When writing tutorials, sample scripts, or docs that surface numerical results: cite the source. Don’t quote benchmarks against papers without naming the paper.
When you implement something citable — the implementing chat’s job¶
If your work adds (or routes for the first time) anything in the mandatory list above — a new method, functional, basis set, ECP, dispersion model, accelerator, dependency, or any other piece of code that traces to a publication or a third-party package — the same merge that lands the code must:
Add the citable entry to the citation database at
python/vibeqc/output/citations/database.toml. New[entries.<key>]block per the schema documented in the file header. If the work is basissetdev-conditional, the entry goes in the siblingdatabase_basissetdev.toml(see § 4 + AGENTS.md § 8) — not onmain.Wire the route in the appropriate
[routes.*]table soassemble(plan)fires the citation when a job actually uses the feature. A new dispersion correction lands aroutes.methods.<dispkey>line; a new functional lands aroutes.functionals.<funcname>line; a new linked library lands aroutes.libraries.<libname>line; a new basis ships underroutes.basis_sets.<lowercase-name>or relies on its inline! Originating publication:header. A citation without a route is silently dead weight.Mark the print flag on the entry. The optional
printfield on[entries.<key>]is the user-visibility gate:print = true(the default) — the entry appears in the end-of-run references block (.out/.references/.bibtex) that users copy-paste into a paper. Pick this for anything a paper’s “Methods” section should cite (methods, functionals, basis sets, ECPs, scientific algorithms, …).print = false— the entry is confined to the.systemmanifest as internal provenance only. Pick this for link-time-only infrastructure that is not a scientific dependency (pybind11, header-only utility libraries, build- time tooling). When in doubt, default totrue.
The runtime collector lives in
python/vibeqc/output/citations/registry.py—CitationDatabase.assemble(...)walks the routes for a job, deduplicates, and returns anAssembledCitations. The.printableview (filtered toprint = true) feeds the references block and the.bibtexsibling; the full.citationsview feeds the.systemmanifest. Implementing chats don’t normally call the collector directly — they make the route fire by putting the entry + route in the database and let the SCF log assemble at end-of-run.Update the coverage tests. If your basis / functional pin sits in
tests/test_basis_citation_coverage.pyor a sibling, extend the pinned set in the same commit so the gate captures your addition rather than leaving the next chat to backfill it.Verify the citation reaches the destinations you marked before pushing: a tiny SCF should land your
print = trueentries in the.outreferences block + the.bibtex/.referencessiblings, and every entry regardless of flag in the.systemmanifest.
Rationale: the citation database is the single source of truth
for what vibe-qc claims it cites. Letting a feature commit land
without its citation entry is how attribution silently breaks
between releases. The pob-* audit thread on 2026-05-24 (commits
22aface3 → 8267c9c9 → 0e6f6df4 → f2a7419c → d422dc2c)
is the canonical example of the cost: a README-pointer header
survived review because no test pinned the DOI mechanically, and
the affected bases shipped with broken attribution until the
audit caught it.
Inline formula + reference-value comments in code¶
When a chat is implementing math from a published paper, the
formula and any published numerical values the implementation is
validated against go into inline comments at the relevant code
sites. The maintainer often keeps PDFs of the cited papers in a
gitignored references/ folder at the project root for
personal use during development; the inline comments are the
only public-facing record of what equation the code is
implementing and how anyone can verify it without leaving the
source file.
Pattern — the equation citation goes immediately above the implementation it derives, naming the paper + equation / section / page:
# Eq. 17 of Sun, Berkelbach, McClain & Chan, J. Chem. Phys. 147,
# 164119 (2017), doi:10.1063/1.4998644:
# L_pq(k) = sum_R exp(-i k·R) L_pq(R)
def build_lpq_at_k(...):
...
Pattern — the published target value for validation goes immediately at the constant or in the test, naming the paper
table / figure row:
# Published target: E_HF = -1.12013988 Ha for H₂/STO-3G/12-bohr
# at kmesh (2,1,1) (Sun-Berkelbach 2017, Table II row 3).
E_HF_REF = -1.12013988
# Within 5 mHa of PySCF KRHF.density_fit() on the same system.
TOL_MHA = 5e-3
The .bibtex sidecar above records WHY the paper is cited for
the user-facing audit trail; these inline comments record WHAT
the code is doing and HOW it is verified — for future maintainers,
for cross-code parity reviewers, and for audit cycles by external
reviewers (including LLM-based audits) who shouldn’t have to
re-derive the math from a PDF that’s only in someone’s local
references/ folder.
Doesn’t apply to textbook equations with no single canonical source (Schrödinger equation, basic linear algebra), or constants from CODATA / NIST / well-known reference tables that are part of the field’s shared background.
When a chat adds an inline reference number it didn’t already
have access to, the same merge that lands the reference value
should add the paper to the citation database (database.toml,
per the previous subsection) — the inline comment and the
.bibtex entry are two ends of the same provenance chain.
9. Scope + dependency discipline¶
vibe-qc maintains a small, deliberate footprint:
No grand refactors without maintainer approval. Even good refactors cost review time; surface the proposal before starting the work.
Every commit ships green — pre-commit hooks must pass; CI must pass; tests must pass. If a hook fails, fix the cause and re-commit; don’t
--no-verifypast it.Don’t add dependencies casually. New native deps (libxxx) need a roadmap conversation; new Python deps belong in optional extras (
[fetch],[ase], etc.) unless truly core. Every dependency adds a build-matrix entry, a licensing question, and ongoing maintenance burden.Asks back to the maintainer — be specific. “Should X ship in v0.8.0 or slip?” beats “thoughts on X?”. Concrete questions with framed alternatives close fastest.
10. External programs vs vendored libraries¶
vibe-qc has its own implementation of every quantum-chemistry method we ship. No part of vibe-qc’s runtime depends on another QC program’s runtime to compute energies, gradients, properties, or anything else user-facing.
Allowed imports / runtime dependencies — numerical + infrastructure libraries that we link against:
libint— Gaussian integrals (LGPL 3.0 library; vendored)libxc— 500+ XC functionals (MPL 2.0; vendored)spglib— crystal symmetry (BSD 3-Clause; vendored)libecpint— ECP integrals (MIT; vendored)Eigen— linear algebra (MPL 2.0; header-only)FFTW3— FFT (GPL v2; vendored — see § 1 for the GPL combined-binary caveat)pybind11— Python bindings (BSD 3-Clause; header-only)ASE— atomic-structure dataclasses + file I/O + the Calculator interface (LGPL 2.1+; used as a Python library, not as a QC engine)NumPy / SciPy — base scientific-Python stack
These are libraries — function calls you make into for a specific numerical service. They don’t compute SCF energies on their own; they give you the building blocks.
Forbidden imports / runtime dependencies — other QC programs:
PySCF, Psi4, ORCA, Turbomole, CRYSTAL, NWChem, GAMESS, Q-Chem, Molpro, ADF, CP2K, VASP, Quantum Espresso, xTB, …
These are programs — they run on their own and compute their
own SCF energies. vibe-qc never imports any of them inside
python/vibeqc/ or cpp/. The litmus test is simple: “does
this run on its own as a quantum-chemistry program?” If yes,
it’s external; if no, it’s a library.
Parity testing — the subprocess pattern¶
When we need to compare against an external program for parity
or benchmark validation, we execute it out-of-process via a
subprocess runner that parses the program’s output. The pattern
lives at examples/regression/runner_<program>.py:
# examples/regression/runner_pyscf.py — spawns PySCF as a
# subprocess; parses its output; never imports pyscf inside
# vibe-qc's core code.
This is what landed in commits 545db04 Retire in-process PySCF periodic backend + 7ab9384 Run PySCF references out of process + d451b84 Record external validation boundary in manifest. The
.system manifest records which
external programs were involved in any parity check, so the
provenance is preserved.
Build-time tooling is allowed¶
Tools used at build/dev time — e.g. basis_set_exchange
(BSE) in scripts/basisset_dev/fetch_from_bse.py, pytest in
tests, sphinx-build for docs — are fine because they’re not
on the runtime path. The rule is about what import vibeqc and
the C++ core link against, not about what helps us develop.
Why this matters¶
No external runtime requirement — end users
pip install vibe-qcand the code runs. No “you also need PySCF installed”.Clean licensing surface — every runtime dependency has a documented license in
docs/license.md. No transitive PySCF / Psi4 / ORCA license concerns.No silent algorithm imports — if vibe-qc says it computes RKS-PBE periodic energies, that means vibe-qc’s own C++ + Python computes them. It doesn’t mean “we wrapped PySCF and called its KRKS for you”.
Validation against external programs is honest — subprocess runners produce reproducible artefacts the external program would have produced anyway, parsed independently. We’re comparing two implementations, not the same implementation against itself.
If you’re tempted to add import pyscf (or any other external
QC program) to anything in python/vibeqc/ or cpp/: stop
and ask the maintainer first. See § 11 below.
Pre-trained model engines (MLIPs) — admitted by exception¶
Machine-learning interatomic potentials (e.g. ACEsuit MACE,
method="mace", python/vibeqc/mlip/) are an explicit,
maintainer-approved exception to the “own implementation” rule above.
Unlike libint/libxc (numerical building blocks vibe-qc orchestrates) or
the semiempirical platform (vibe-qc’s own code), an MLIP is the whole
calculation: vibe-qc marshals geometry in and reads energy/forces/stress
out of a third-party pre-trained model. The discipline for these:
Optional extras, never core. The heavy ML stack ships behind an extra (
[mace]) and is import-gated.Attribute, never claim. vibe-qc names the model and cites its papers in every run; outputs must not present the energy as vibe-qc’s own (it is the model’s reference-shifted DFT-surface value, not a vibe-qc total electronic energy).
Weights fetched on demand, never bundled, with each model’s license surfaced (MIT ungated; academic/ASL gated behind a non-commercial acknowledgment).
This admits pre-trained model inference as an attributed external engine. It does not relax the ban on importing external QC programs (PySCF, ORCA, …) to compute energies — those remain forbidden.
11. When to escalate to the maintainer¶
If you hit any of these, stop and ask, don’t decide unilaterally:
Licensing question on a new bundled dataset.
Branch-policy edge case (force-push, hook bypass, tag).
Decision affecting CHANGELOG / release notes wording.
Anything that contradicts a standing rule above.
Anything you’d describe as “I’m pretty sure this is fine but…”
Asking has very low cost. Wrong-and-pushed has high cost.
12. Privacy / personal-info hygiene¶
vibe-qc is public on gitlab.peintinger.com/mpei/vibeqc. Before
committing, make sure nothing in the diff would expose:
Credentials — passwords, API keys, tokens, bearer/auth headers, SSH private keys,
.envfiles, anything from~/.ssh/. Treat any leak here as a security incident perSECURITY.md.Real IP addresses — especially private LAN IPs (
192.168.x.x,10.x.x.x). Use<host>or a documented hostname alias.Author home paths — never write
/Users/<name>/...or/home/<name>/...into committed content. Use~/,/home/USER/, or a placeholder (<vibe-qc-checkout>,<your-orca-install>). This applies to reference outputs that captured a real run too — sanitize before committing.Identity — the public maintainer identity is
mpei@vibe-qc.com(perCONTRIBUTING.md/SECURITY.md). Don’t introduce other names / emails / employer affiliations into repo content.
A pre-commit hook at .githooks/pre-commit enforces a subset
(<home>, /home/mpei, smart-steel-technologies).
Activate once per clone — see
CONTRIBUTING.md § “Pre-commit hook”. The
hook bypass rules from § 2 apply: --no-verify only when the
maintainer explicitly asks, with the reason in the commit
message.
Historical author/committer email metadata is display-normalized
to mpei@vibe-qc.com via .mailmap. Default git log, git blame, git shortlog, GitLab UI all honor it. Raw
git log --pretty='%ae' (lowercase) still shows the stored
email; that’s intentional — main’s “never force-push to main”
rule (§ 2) precludes a history rewrite. Append a line to
.mailmap to remap an additional historical email.
13. Release operations are release-chat-owned¶
Tagging vX.Y.Z and advancing the release branch are exclusively
the release chat’s job. To request inclusion of a commit in a patch
release, add a Patch-candidate: trailer to the commit body — same
format as Signed-off-by: / Co-Authored-By::
fix(scf): handle near-null overlap on degenerate basis
Pre-fix, the SAD constructor crashed at min(eig(S)) < 1e-10.
Falls back to Hcore guess.
Patch-candidate: v0.7.x
Co-Authored-By: ...
Valid trailer values:
v0.7.x— next patch on the 0.7 line (e.g. v0.7.12)v0.8.x— next patch on the 0.8 line, once v0.8.0 shipsv0.8.0— specifically the upcoming minor release(omitted) — not patch-target; rides to the next minor
Multiple targets allowed, comma-separated:
Patch-candidate: v0.7.x, v0.8.0.
For commits already pushed (can’t amend without rewriting history,
which § 2 forbids on main), attach the trailer via git notes:
git notes add -m "Patch-candidate: v0.7.x" <SHA>
git push origin refs/notes/commits
Or simply message the release chat with the SHA + reasoning; they’ll add the note for you and treat it the same.
The release chat scans main for trailered commits when cutting
each patch, cherry-picks the curated candidates onto a hotfix
branch off the previous tag, tags from there, and fast-forwards
release to the new tag. See
docs/release_process.md for the full
flow (§ “Cutting a patch release” + § “How candidates are
flagged”).
Do not:
push directly to
releasecreate
vX.Y.Ztagsopen MRs targeting
release
GitLab protected-branch + protected-tag rules (landed 2026-05-15)
enforce this mechanically: release allows no merges and no
non-Maintainer pushes; tags matching v* require Maintainer role
to create. The trailer is the only correct channel for asking
“include my commit in the next patch.”
This rule exists because three release-process violations between
2026-05-08 and 2026-05-15 each caused a recovery cycle (orphan
tags v0.7.5 / v0.7.9 / v0.7.10 on origin are the dormant
monuments). The shortcut pattern: chats treated release as the
destination they should aim at, rather than the destination that
main → tag ff’s into automatically. The trailer + branch
protection together reverse that intuition.
14. Stay wired into main — land small, ship release-ready¶
The v0.8.x and v0.9 releases were painful because dev chats
drifted from main and landed work that compiled but left
main half-finished — stale docs, an inaccurate CHANGELOG
[Unreleased], ungated incomplete features. The release chat
then had to gate, audit, and clean up before it could tag. The
discipline below makes that audit unnecessary: every chat keeps
its slice of main release-ready as it goes.
Land small, landable increments¶
Break work into milestones that are each independently shippable — a coherent change that builds green and could be tagged on its own.
Keep each milestone small enough to review in one sitting.
Land each milestone on
main(rebase-then-push, § 2) before starting the next. Don’t stack multiple un-landed milestones — that is how branches diverge.
Definition of done — main stays release-ready¶
A milestone is not done until, repo-wide (not just the files you touched), all of these hold. Verify them before every push:
Full build + full test suite green — C++ and Python. If you touched shared code, run its consumers, not just your area.
CI green on
mainafter the push. Thebuild-testjob is the build-break gate; if your push reds it, fixing that is your only next task.No half-finished code paths. Every path you added either fully works or is unreachable.
Incomplete-by-design work is gated by you, now — feature flag, experimental marker, or basissetdev-conditional (§ 4) — with the gating decision documented. Never leave the release chat to discover that something needs gating.
CHANGELOG
[Unreleased]reflects reality: it lists what you actually landed and claims only what is done and tested. Don’t over-claim — the release chat audits this against the tree.Docs are in parity this milestone, per the lightweight-ongoing cadence (§ 5): user guide, API docs, banner / sample output (§ 6), roadmap “shipped” sweep,
docs/license.mdif deps or data changed.No papered-over bugs (§ 7); privacy + licensing surface clean (§ 1, § 12).
This checklist is a gate, not a wishlist — a push that can’t pass it is not ready to land.
Review what moved on main — after every sync¶
A clean git rebase resolves textual conflicts only. It will
not catch a changed API signature, a shared helper whose
behaviour changed, or an assumption that no longer holds — other
chats land on main in parallel (§ 3). After every git pull --rebase:
Read what landed since your last sync:
git log --oneline <last-sync-SHA>..origin/mainandgit diff <last-sync-SHA>..origin/main -- <your files>.Decide explicitly whether any of it touches your area. If it does, re-read the changed code, re-run the affected tests against the new
main, and reconcile your plan. If the move is large enough that your plan no longer fits, stop and re-plan rather than forcing stale work on top.This matters most when a chat resumes after being idle — assume
mainhas moved a lot and review accordingly.
Keep a persistent handover file¶
Maintain one always-current handover file so any other agent or session can resume cold:
During a release cycle, that is your drop-box file
.release-status/v0.X.0/<chat-id>.md(§ 3).For a long-lived workstream, that is a handover under
handovers/(handovers/HANDOVER_<TOPIC>.md; seehandovers/HANDOVER_META_GGA.md,handovers/HANDOVER_MP2_PARITY.md, …).handovers/README.mdis the index; concluded workstreams are retired (deleted) there once landed, recoverable via git history.Update it at every milestone. It must carry: current progress
branch tip SHA + the
mainSHA you last synced to; completed work (per item: what, SHA, tests); next steps in priority order; blockers, assumptions, and key decisions with their reasoning; anything gated or deferred and why.
If a milestone can’t be made release-ready — CI won’t go green, a conflict needs another chat, a feature can’t be cleanly gated — stop and resolve it before building further (§ 11: asking is cheap, wrong-and-pushed is expensive).
15. Running anything on planetx or mars — use vq, don’t write to the git checkouts¶
The shared compute hosts (planetx, mars) host
/home/USER/gitlab/vibeqc-{dev,release,queue}/ git checkouts that
are managed exclusively by vq admin update. Hand-edits, untracked
files, or local commits in those trees break the next deployment
(2026-05-25 incident: 108-file untracked-dir collision on planetx,
141 modified basis files on mars, each costing an hour to untangle).
The rule for every dev chat that needs to run something on
planetx or mars: submit work via vq with a payload. The daemon
gives you:
A clean per-job workspace (your submitted source).
A per-job scratch workdir at
$VQ_WORKDIR(the env var the daemon injects). Write all intermediate / large data there.Result readback via
vq logs JOBID/vq fetch JOBID/vq status JOBID(the workdir path is in the status output).
To request a code or example landing in vibe-qc itself, submit
with --tag pr-request and a descriptive --job-name; the
maintainer reviews terminal jobs with that tag.
Forbidden on planetx + mars (will be reverted without notice):
Writing to
/home/USER/gitlab/vibeqc-*/.Running
git pull/git checkout/bash scripts/update.shon those repos.Running
pip install/make/ build commands inside them.Modifying anything under
/etc/vq/,/opt/vq/, or another user’s/var/lib/vq/users/<uid>/.
Full protocol + recipe table:
vibe-queue/docs/agent_interaction.md.
Read it once before your first vq invocation on those hosts. The
queue chat owns updates to that doc; if it’s ambiguous, submit a
pr-request against the queue chat to clarify it rather than
inventing your own workflow.
See also¶
docs/release_process.md— branch model, release procedure, documentation cadence,Patch-candidateconsumption flow.docs/license.md— full licensing + bundled-data inventory.docs/roadmap.md— long-term plan + tutorial parity audit.docs/release_v0_8_0_prep.md— canonical example of the per-tag mechanical-sprint playbook (copy-and-adapt for future releases).vibe-queue/docs/agent_interaction.md— protocol for running work on planetx + mars (per § 15).~/.claude/projects/-Users-mpei-mpei-documents-vibeqc/memory/MEMORY.md— user-level / per-machine specifics (NOT a substitute for this file).