CLI ignores --data-dir for the store: repo policy/wal/compact/import read and write the default store #611

Closed
opened 2026-09-15 23:05:07 +00:00 by crueber · 1 comment
Owner

Evidence (live field test, scratch stack :18099, throwaway repo field/demo)

  • walhub --data-dir /tmp/field-data repo policy set --file policy.json field/demo exits 0 but writes to ~/.local/share/walhub/store/… (the ResolveDataDir default), not /tmp/field-data/store. Proven: --data-dir /tmp/does-not-exist-xyz repo policy get still returns the doc (flag provably ignored); config dump --data-dir /tmp/field-data prints store.root = /home/crueber/.local/share/walhub/store.
  • Consequence in the field test: a required-reviews policy appeared to be set while the server ran unprotected — a merge that should have been refused succeeded (PR #3). The gate itself works once the policy actually reaches the server (verified after placing the file correctly: conflict: required-reviews: need 1 approvals, have 0).

Mechanism (static read)

  • config.Load resolves its working data dir from ResolveDataDir(getenv) (env/defaults only); the peeled --data-dir flag (c.dataDir) is never threaded in. Candidates come from defaultConfigPaths(c) (flag-aware), but with no file present FirstRunDefaults uses the env-resolved dir — so Store.Root/Cache.Dir point at the default store.
  • serve repairs this with the flag-sync fixup (serve.go:63-69 — re-points flag-derived Store.Root/Cache.Dir, preserving explicit file values and the env overlay). The CLI path (openEngine → dataDirFor + openStore, which prefers cfg.Store.Root) has no such sync, so every CLI subcommand (repo policy/settings, wal, compact, bundle, import, repo create, config dump/check) operates on the wrong store whenever --data-dir differs from the default.
  • Env form (WALHUB_DATA_DIR=/tmp/field-data) works correctly — only the flag is dropped.

What's requested

Apply the serve-style flag sync (flag-derived DataDir/Store.Root/Cache.Dir only, explicit file values and env overlay preserved) in the shared CLI path (resolveConfig or openEngine) so all subcommands honor --data-dir. Serve's fixup becomes redundant but harmless (idempotent).

Acceptance criteria

  • --data-dir X repo policy set/get, config dump, and the other store-touching subcommands all operate under X (proven with a nonexistent X failing/empty rather than leaking to the default).
  • Explicit store.root in a config file still wins over --data-dir; WALHUB__STORE__* overrides still win.
  • Unit test pins the sync (flag dir vs env default vs explicit file matrix).
## Evidence (live field test, scratch stack :18099, throwaway repo field/demo) - `walhub --data-dir /tmp/field-data repo policy set --file policy.json field/demo` exits 0 but writes to `~/.local/share/walhub/store/…` (the ResolveDataDir default), not /tmp/field-data/store. Proven: `--data-dir /tmp/does-not-exist-xyz repo policy get` still returns the doc (flag provably ignored); `config dump --data-dir /tmp/field-data` prints `store.root = /home/crueber/.local/share/walhub/store`. - Consequence in the field test: a required-reviews policy appeared to be set while the server ran unprotected — a merge that should have been refused succeeded (PR #3). The gate itself works once the policy actually reaches the server (verified after placing the file correctly: `conflict: required-reviews: need 1 approvals, have 0`). ## Mechanism (static read) - `config.Load` resolves its working data dir from `ResolveDataDir(getenv)` (env/defaults only); the peeled `--data-dir` flag (`c.dataDir`) is never threaded in. Candidates come from `defaultConfigPaths(c)` (flag-aware), but with no file present `FirstRunDefaults` uses the env-resolved dir — so Store.Root/Cache.Dir point at the default store. - `serve` repairs this with the flag-sync fixup (serve.go:63-69 — re-points flag-derived Store.Root/Cache.Dir, preserving explicit file values and the env overlay). The CLI path (`openEngine` → `dataDirFor` + `openStore`, which prefers cfg.Store.Root) has no such sync, so every CLI subcommand (repo policy/settings, wal, compact, bundle, import, repo create, config dump/check) operates on the wrong store whenever --data-dir differs from the default. - Env form (`WALHUB_DATA_DIR=/tmp/field-data`) works correctly — only the flag is dropped. ## What's requested Apply the serve-style flag sync (flag-derived DataDir/Store.Root/Cache.Dir only, explicit file values and env overlay preserved) in the shared CLI path (`resolveConfig` or `openEngine`) so all subcommands honor --data-dir. Serve's fixup becomes redundant but harmless (idempotent). ## Acceptance criteria - [ ] `--data-dir X repo policy set/get`, `config dump`, and the other store-touching subcommands all operate under X (proven with a nonexistent X failing/empty rather than leaking to the default). - [ ] Explicit store.root in a config file still wins over --data-dir; WALHUB__STORE__* overrides still win. - [ ] Unit test pins the sync (flag dir vs env default vs explicit file matrix).
crueber added this to the v1 milestone 2026-09-15 23:05:07 +00:00
Author
Owner

Fixed by #614 (merged): shared syncDataDirFlag in resolveConfig re-points flag-derived DataDir/Store.Root/Cache.Dir (explicit file values + WALHUB__* overlay preserved); serve fixup kept as idempotent no-op. Verified: matrix red-on-main/green-on-fix, cmd/config suites -race green, live-binary proof (no default leak), independent review APPROVE.

Fixed by #614 (merged): shared syncDataDirFlag in resolveConfig re-points flag-derived DataDir/Store.Root/Cache.Dir (explicit file values + WALHUB__* overlay preserved); serve fixup kept as idempotent no-op. Verified: matrix red-on-main/green-on-fix, cmd/config suites -race green, live-binary proof (no default leak), independent review APPROVE.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#611
No description provided.