feat: unify state dir to ~/.qmax with first-run migration - #8
Merged
Conversation
Persistent state (config/auth, receipts, the ed25519 signing key) lived in ~/.qamax (historical "QA Max") while the binary installs to ~/.qmax. Unify everything under ~/.qmax. - config.go: configDirName .qamax -> .qmax. - main.go: set receipt.BaseDir = ~/.qmax and run migrateLegacyStateDir() first, before any config read or receipt write. - migrate.go: merge legacy ~/.qamax state into ~/.qmax entry-by-entry (never clobbering the binary dir's existing files); best-effort + idempotent, so existing logins and the agent signing identity survive the rename. - install.sh: CONFIG_DIR -> ~/.qmax. - migrate_test.go: covers the move, no-clobber, idempotency, and no-legacy no-op. No receipt-module change needed — the agent sets receipt.BaseDir explicitly.
✅ QualityMax Pipeline
Powered by QualityMax — AI-Powered Test Automation |
…tranded The first version skipped a whole legacy subdirectory when the destination subdirectory already existed — so if ~/.qmax/receipts already existed (e.g. after an upgrade or an overlapping old daemon), every remaining ~/.qamax/receipts file became unreachable. Recurse into subdirectories, moving file-by-file and preserving any destination file. Adds TestMigrateMergesReceiptsRecursively (both receipts/ dirs present, incl. a same-named no-clobber case).
Desperado
added a commit
that referenced
this pull request
Jul 13, 2026
The bump was intended for #8 but missed its squash. Version is the source of qmax --version and receipts' agent_version; bump before tagging v4.5.0 so the released binary and the tag agree.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Unifies the agent's on-disk state directory to
~/.qmax(state was in~/.qamax, binary already in~/.qmax), with a safe first-run migration.Why
Persistent state —
config.json(auth token + agent registration), thereceipts/dir, and the ed25519 receipt signing key — lived in~/.qamax(historical "QA Max"), while the binary installs to~/.qmax. Theqamaxname is legacy; the brand/command isqmax. This removes the split.Change
config.go:configDirName.qamax→.qmax.main.go: setsreceipt.BaseDir = ~/.qmaxand runsmigrateLegacyStateDir()first, before any config read or receipt write.migrate.go: recursively merges legacy~/.qamaxstate into~/.qmax(a dir rename won't work —~/.qmaxalready exists, holding the binary). Directories are merged file-by-file, never overwriting an existing destination file; best-effort + idempotent — existing logins and the agent's signing identity survive the rename, and legacy receipts stay reachable even when~/.qmax/receiptsalready exists.migrate_test.go: covers the flat move + no-clobber + idempotency, the recursive receipts merge with both dirs present (incl. same-named no-clobber), and the no-legacy no-op.install.shneeds no change — it already uses~/.qmax.Verification
go build/go vet/golangci-lint/ migration tests all green.receipt.BaseDirexplicitly.Note: two
TestHeartbeatLoop_*tests are flaky on macOS only (sysmetrics shells a slowtop -l 1, eating the test's time budget) — pre-existing, reproduces onmain, passes on Linux CI. Unrelated to this change.