Skip to content

Commit ee4fa21

Browse files
fix(miner): delegate three resolve*DbPath helpers to resolveLocalStoreDbPath (#8336) (#8524)
1 parent 1d83593 commit ee4fa21

9 files changed

Lines changed: 85 additions & 52 deletions

File tree

apps/loopover-ui/src/lib/ams-env-reference.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const AMS_ENV_REFERENCE_ROWS: MinerEnvReferenceRow[] = [
3838
},
3939
{
4040
name: "LOOPOVER_MINER_CONFIG_DIR",
41-
firstReference: "lib/deny-hook-synthesis.ts",
41+
firstReference: "lib/laptop-init.ts",
4242
defaultValue: "",
4343
},
4444
{
@@ -64,7 +64,7 @@ export const AMS_ENV_REFERENCE_ROWS: MinerEnvReferenceRow[] = [
6464
{
6565
name: "LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB",
6666
firstReference: "lib/deny-hook-synthesis.ts",
67-
defaultValue: "",
67+
defaultValue: null,
6868
},
6969
{
7070
name: "LOOPOVER_MINER_DISABLE_EGRESS_FIREWALL",
@@ -106,6 +106,11 @@ export const AMS_ENV_REFERENCE_ROWS: MinerEnvReferenceRow[] = [
106106
firstReference: "lib/governor-state.ts",
107107
defaultValue: null,
108108
},
109+
{
110+
name: "LOOPOVER_MINER_LAPTOP_STATE_DB",
111+
firstReference: "lib/laptop-init.ts",
112+
defaultValue: null,
113+
},
109114
{
110115
name: "LOOPOVER_MINER_LOG_LEVEL",
111116
firstReference: "lib/logger.ts",
@@ -134,7 +139,7 @@ export const AMS_ENV_REFERENCE_ROWS: MinerEnvReferenceRow[] = [
134139
{
135140
name: "LOOPOVER_MINER_ORB_EXPORT_DB",
136141
firstReference: "lib/orb-export.ts",
137-
defaultValue: "",
142+
defaultValue: null,
138143
},
139144
{
140145
name: "LOOPOVER_MINER_PLAN_STORE_DB",
@@ -241,12 +246,12 @@ export const AMS_ENV_REFERENCE_MARKDOWN = [
241246
"| `LOOPOVER_MINER_AMS_POLICY_PATH` | `lib/ams-policy.ts` | (none) |",
242247
"| `LOOPOVER_MINER_ATTEMPT_LOG_DB` | `lib/attempt-log.ts` | (none) |",
243248
"| `LOOPOVER_MINER_CLAIM_LEDGER_DB` | `lib/claim-ledger.ts` | (none) |",
244-
'| `LOOPOVER_MINER_CONFIG_DIR` | `lib/deny-hook-synthesis.ts` | `""` |',
249+
'| `LOOPOVER_MINER_CONFIG_DIR` | `lib/laptop-init.ts` | `""` |',
245250
"| `LOOPOVER_MINER_CONTRIBUTION_PROFILE_CACHE_DB` | `lib/contribution-profile-cache.ts` | (none) |",
246251
'| `LOOPOVER_MINER_CONTROL_PLANE` | `lib/tenant-client.ts` | `""` |',
247252
'| `LOOPOVER_MINER_CONTROL_PLANE_ADMIN_TOKEN` | `lib/tenant-client.ts` | `""` |',
248253
'| `LOOPOVER_MINER_CONTROL_PLANE_URL` | `lib/tenant-client.ts` | `""` |',
249-
'| `LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB` | `lib/deny-hook-synthesis.ts` | `""` |',
254+
"| `LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB` | `lib/deny-hook-synthesis.ts` | (none) |",
250255
"| `LOOPOVER_MINER_DISABLE_EGRESS_FIREWALL` | `lib/generate-egress-firewall-config.ts` | (none) |",
251256
'| `LOOPOVER_MINER_DISCOVERY_INDEX_URL` | `lib/discovery-index-client.ts` | `""` |',
252257
'| `LOOPOVER_MINER_DISCOVERY_PLANE` | `lib/discovery-index-client.ts` | `""` |',
@@ -255,12 +260,13 @@ export const AMS_ENV_REFERENCE_MARKDOWN = [
255260
"| `LOOPOVER_MINER_EVENT_LEDGER_DB` | `lib/event-ledger.ts` | (none) |",
256261
"| `LOOPOVER_MINER_GOVERNOR_LEDGER_DB` | `lib/governor-ledger.ts` | (none) |",
257262
"| `LOOPOVER_MINER_GOVERNOR_STATE_DB` | `lib/governor-state.ts` | (none) |",
263+
"| `LOOPOVER_MINER_LAPTOP_STATE_DB` | `lib/laptop-init.ts` | (none) |",
258264
'| `LOOPOVER_MINER_LOG_LEVEL` | `lib/logger.ts` | `""` |',
259265
"| `LOOPOVER_MINER_NEON_API_KEY` | `lib/egress-allowlist.ts` | (none) |",
260266
"| `LOOPOVER_MINER_NEON_PARENT_BRANCH_ID` | `lib/egress-allowlist.ts` | (none) |",
261267
"| `LOOPOVER_MINER_NEON_PROJECT_ID` | `lib/egress-allowlist.ts` | (none) |",
262268
'| `LOOPOVER_MINER_NO_UPDATE_CHECK` | `lib/update-check.ts` | `""` |',
263-
'| `LOOPOVER_MINER_ORB_EXPORT_DB` | `lib/orb-export.ts` | `""` |',
269+
"| `LOOPOVER_MINER_ORB_EXPORT_DB` | `lib/orb-export.ts` | (none) |",
264270
"| `LOOPOVER_MINER_PLAN_STORE_DB` | `lib/plan-store.ts` | (none) |",
265271
"| `LOOPOVER_MINER_POLICY_DOC_CACHE_DB` | `lib/policy-doc-cache.ts` | (none) |",
266272
"| `LOOPOVER_MINER_POLICY_VERDICT_CACHE_DB` | `lib/policy-verdict-cache.ts` | (none) |",

packages/loopover-engine/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ have a root test under `test/unit/` (e.g. `test/unit/reviewer-consensus-calibrat
4141
`src/miner/loop-reentry-policy.ts`#8347). The package-local `node:test` suite remains the package's
4242
own gate; the root mirror is what makes the same scenarios gradeable by Codecov.
4343

44+
Miner path-resolution refactors that only touch `packages/loopover-miner/lib/**` (e.g. delegating
45+
`resolve*DbPath` to `resolveLocalStoreDbPath`#8336) also keep this README line so CI's `engine`
46+
path filter trips and validate-tests runs the **unscoped** suite: scoped `--changed` +
47+
`--coverage.all=false` has uploaded empty patch coverage for those miner lib lines even when the
48+
matching `test/unit/miner-*.test.ts` files passed (#8496).
49+
4450
## `opportunity-ranker`
4551

4652
The Phase-1 miner-discovery ranker. It composes five already-normalized `[0, 1]` signals into one ordinal score:

packages/loopover-miner/docs/env-reference.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ Generated by `npm run miner:env-reference`. Do not edit manually.
1010
| `LOOPOVER_MINER_AMS_POLICY_PATH` | `lib/ams-policy.ts` | (none) |
1111
| `LOOPOVER_MINER_ATTEMPT_LOG_DB` | `lib/attempt-log.ts` | (none) |
1212
| `LOOPOVER_MINER_CLAIM_LEDGER_DB` | `lib/claim-ledger.ts` | (none) |
13-
| `LOOPOVER_MINER_CONFIG_DIR` | `lib/deny-hook-synthesis.ts` | `""` |
13+
| `LOOPOVER_MINER_CONFIG_DIR` | `lib/laptop-init.ts` | `""` |
1414
| `LOOPOVER_MINER_CONTRIBUTION_PROFILE_CACHE_DB` | `lib/contribution-profile-cache.ts` | (none) |
1515
| `LOOPOVER_MINER_CONTROL_PLANE` | `lib/tenant-client.ts` | `""` |
1616
| `LOOPOVER_MINER_CONTROL_PLANE_ADMIN_TOKEN` | `lib/tenant-client.ts` | `""` |
1717
| `LOOPOVER_MINER_CONTROL_PLANE_URL` | `lib/tenant-client.ts` | `""` |
18-
| `LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB` | `lib/deny-hook-synthesis.ts` | `""` |
18+
| `LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB` | `lib/deny-hook-synthesis.ts` | (none) |
1919
| `LOOPOVER_MINER_DISABLE_EGRESS_FIREWALL` | `lib/generate-egress-firewall-config.ts` | (none) |
2020
| `LOOPOVER_MINER_DISCOVERY_INDEX_URL` | `lib/discovery-index-client.ts` | `""` |
2121
| `LOOPOVER_MINER_DISCOVERY_PLANE` | `lib/discovery-index-client.ts` | `""` |
@@ -24,12 +24,13 @@ Generated by `npm run miner:env-reference`. Do not edit manually.
2424
| `LOOPOVER_MINER_EVENT_LEDGER_DB` | `lib/event-ledger.ts` | (none) |
2525
| `LOOPOVER_MINER_GOVERNOR_LEDGER_DB` | `lib/governor-ledger.ts` | (none) |
2626
| `LOOPOVER_MINER_GOVERNOR_STATE_DB` | `lib/governor-state.ts` | (none) |
27+
| `LOOPOVER_MINER_LAPTOP_STATE_DB` | `lib/laptop-init.ts` | (none) |
2728
| `LOOPOVER_MINER_LOG_LEVEL` | `lib/logger.ts` | `""` |
2829
| `LOOPOVER_MINER_NEON_API_KEY` | `lib/egress-allowlist.ts` | (none) |
2930
| `LOOPOVER_MINER_NEON_PARENT_BRANCH_ID` | `lib/egress-allowlist.ts` | (none) |
3031
| `LOOPOVER_MINER_NEON_PROJECT_ID` | `lib/egress-allowlist.ts` | (none) |
3132
| `LOOPOVER_MINER_NO_UPDATE_CHECK` | `lib/update-check.ts` | `""` |
32-
| `LOOPOVER_MINER_ORB_EXPORT_DB` | `lib/orb-export.ts` | `""` |
33+
| `LOOPOVER_MINER_ORB_EXPORT_DB` | `lib/orb-export.ts` | (none) |
3334
| `LOOPOVER_MINER_PLAN_STORE_DB` | `lib/plan-store.ts` | (none) |
3435
| `LOOPOVER_MINER_POLICY_DOC_CACHE_DB` | `lib/policy-doc-cache.ts` | (none) |
3536
| `LOOPOVER_MINER_POLICY_VERDICT_CACHE_DB` | `lib/policy-verdict-cache.ts` | (none) |

packages/loopover-miner/lib/deny-hook-synthesis.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
// refresh + maintainer review before any synthesized rule takes effect. Approved rules merge with
55
// {@link DEFAULT_DENY_RULES}; unapproved proposals never block tool calls. No behavior change.
66
import { chmodSync, mkdirSync } from "node:fs";
7-
import { homedir } from "node:os";
8-
import { dirname, join } from "node:path";
7+
import { dirname } from "node:path";
98
import { DatabaseSync } from "node:sqlite";
109
import {
1110
aggregateBlockerHistory,
@@ -24,6 +23,7 @@ import {
2423
import type { DenyRuleProposal, SynthesisConfig } from "@loopover/engine";
2524
import { DEFAULT_FORGE_CONFIG } from "./forge-config.js";
2625
import type { DenyRule } from "./deny-hooks.js";
26+
import { resolveLocalStoreDbPath } from "./local-store.js";
2727
import { DENY_HOOK_SYNTHESIS_PURGE_SPEC, purgeStoreByRepo } from "./store-maintenance.js";
2828

2929
// Re-export the pure synthesis helpers from the engine so this module's public API is unchanged after #5667
@@ -86,20 +86,7 @@ function normalizeApiBaseUrl(apiBaseUrl?: string): string {
8686
}
8787

8888
export function resolveDenyHookSynthesisDbPath(env: Record<string, string | undefined> = process.env): string {
89-
const explicitPath = typeof env.LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB === "string"
90-
? env.LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB.trim()
91-
: "";
92-
if (explicitPath) return explicitPath;
93-
94-
const explicitConfigDir = typeof env.LOOPOVER_MINER_CONFIG_DIR === "string"
95-
? env.LOOPOVER_MINER_CONFIG_DIR.trim()
96-
: "";
97-
if (explicitConfigDir) return join(explicitConfigDir, defaultDbFileName);
98-
99-
const configHome = typeof env.XDG_CONFIG_HOME === "string" && env.XDG_CONFIG_HOME.trim()
100-
? env.XDG_CONFIG_HOME.trim()
101-
: join(homedir(), ".config");
102-
return join(configHome, "loopover-miner", defaultDbFileName);
89+
return resolveLocalStoreDbPath(defaultDbFileName, "LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB", env);
10390
}
10491

10592
// `dbPath` is always a real string here: this function's only caller (initDenyHookSynthesisStore) already

packages/loopover-miner/lib/laptop-init.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DatabaseSync } from "node:sqlite";
55
import { applySchemaMigrations } from "./schema-version.js";
66
import { reportCliFailure } from "./cli-error.js";
77
import { resolveGitHubToken } from "./github-token-resolution.js";
8+
import { resolveLocalStoreDbPath } from "./local-store.js";
89

910
const githubApiBaseUrl = "https://api.github.com";
1011
const githubApiVersion = "2022-11-28";
@@ -43,9 +44,9 @@ function resolveMinerStateDir(env: Record<string, string | undefined> = process.
4344
return join(configHome, "loopover-miner");
4445
}
4546

46-
/** Path to the laptop-mode SQLite bootstrap file inside the miner state directory. */
47+
/** Path to the laptop-mode SQLite bootstrap file (shared local-store resolution + optional explicit override). */
4748
export function resolveLaptopStateDbPath(env: Record<string, string | undefined> = process.env): string {
48-
return join(resolveMinerStateDir(env), defaultDbFileName);
49+
return resolveLocalStoreDbPath(defaultDbFileName, "LOOPOVER_MINER_LAPTOP_STATE_DB", env);
4950
}
5051

5152
/** Create the state dir and SQLite file. Re-running is idempotent and never clobbers existing rows. */

packages/loopover-miner/lib/orb-export.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { chmodSync, mkdirSync } from "node:fs";
2-
import { homedir } from "node:os";
3-
import { dirname, join } from "node:path";
2+
import { dirname } from "node:path";
43
import { DatabaseSync } from "node:sqlite";
54
import { createHash, createHmac } from "node:crypto";
65
import { generateAnonSecret, hmacAnonymize as engineHmacAnonymize } from "@loopover/engine";
76
import { readPrOutcomes } from "./pr-outcome.js";
87
import type { NormalizedPrOutcomePayload, PrOutcomeLedgerReader } from "./pr-outcome.js";
98
import { initEventLedger } from "./event-ledger.js";
109
import { argsWantJson, describeCliError, reportCliFailure } from "./cli-error.js";
10+
import { resolveLocalStoreDbPath } from "./local-store.js";
1111

1212
// Optional anonymized Orb telemetry export (#4277, network send wired in #5681). The self-host Orb collector
1313
// (src/selfhost/orb-collector.ts, #1255) is ALWAYS-ON for a maintainer's own instance; a miner runs on a
@@ -52,19 +52,7 @@ const CURSOR_KEY = "export_cursor";
5252
const defaultDbFileName = "orb-export.sqlite3";
5353

5454
export function resolveOrbExportDbPath(env: Record<string, string | undefined> = process.env): string {
55-
const explicitPath =
56-
typeof env.LOOPOVER_MINER_ORB_EXPORT_DB === "string" ? env.LOOPOVER_MINER_ORB_EXPORT_DB.trim() : "";
57-
if (explicitPath) return explicitPath;
58-
59-
const explicitConfigDir =
60-
typeof env.LOOPOVER_MINER_CONFIG_DIR === "string" ? env.LOOPOVER_MINER_CONFIG_DIR.trim() : "";
61-
if (explicitConfigDir) return join(explicitConfigDir, defaultDbFileName);
62-
63-
const configHome =
64-
typeof env.XDG_CONFIG_HOME === "string" && env.XDG_CONFIG_HOME.trim()
65-
? env.XDG_CONFIG_HOME.trim()
66-
: join(homedir(), ".config");
67-
return join(configHome, "loopover-miner", defaultDbFileName);
55+
return resolveLocalStoreDbPath(defaultDbFileName, "LOOPOVER_MINER_ORB_EXPORT_DB", env);
6856
}
6957

7058
// `dbPath` is always a real string here: this function's only caller (openOrbExportStore) already defaults its

test/unit/miner-deny-hook-synthesis.test.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { mkdtempSync, rmSync } from "node:fs";
2-
import { tmpdir } from "node:os";
2+
import { homedir, tmpdir } from "node:os";
33
import { join } from "node:path";
44
import { DatabaseSync } from "node:sqlite";
55
import { afterEach, describe, expect, it } from "vitest";
@@ -21,6 +21,7 @@ import type { DenyRuleProposal } from "../../packages/loopover-engine/src/miner/
2121
// #7525: normalizeRepoFullName is defined in the engine and re-exported unchanged by the miner-lib module
2222
// above; import it from the engine source directly so the guard's src branches are the ones exercised.
2323
import { normalizeRepoFullName } from "../../packages/loopover-engine/src/miner/deny-hook-synthesis";
24+
import { resolveLocalStoreDbPath } from "../../packages/loopover-miner/lib/local-store.js";
2425

2526
const tempDirs: string[] = [];
2627
const stores: Array<{ close(): void }> = [];
@@ -60,12 +61,28 @@ describe("resolveDenyHookSynthesisDbPath() (#4522)", () => {
6061
"/custom/d.sqlite3",
6162
);
6263
expect(resolveDenyHookSynthesisDbPath({ LOOPOVER_MINER_CONFIG_DIR: "/custom/config" })).toBe(
63-
"/custom/config/deny-hook-synthesis.sqlite3",
64+
join("/custom/config", "deny-hook-synthesis.sqlite3"),
6465
);
6566
expect(resolveDenyHookSynthesisDbPath({ XDG_CONFIG_HOME: "/xdg" })).toBe(
66-
"/xdg/loopover-miner/deny-hook-synthesis.sqlite3",
67+
join("/xdg", "loopover-miner", "deny-hook-synthesis.sqlite3"),
6768
);
68-
expect(resolveDenyHookSynthesisDbPath({})).toMatch(/\/\.config\/loopover-miner\/deny-hook-synthesis\.sqlite3$/);
69+
expect(resolveDenyHookSynthesisDbPath({})).toBe(
70+
join(homedir(), ".config", "loopover-miner", "deny-hook-synthesis.sqlite3"),
71+
);
72+
});
73+
74+
it("stays byte-identical to resolveLocalStoreDbPath for representative env combinations (#8336)", () => {
75+
const cases: Array<Record<string, string | undefined>> = [
76+
{ LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB: "/custom/d.sqlite3" },
77+
{ LOOPOVER_MINER_CONFIG_DIR: "/custom/config" },
78+
{ XDG_CONFIG_HOME: "/xdg" },
79+
{},
80+
];
81+
for (const env of cases) {
82+
expect(resolveDenyHookSynthesisDbPath(env)).toBe(
83+
resolveLocalStoreDbPath("deny-hook-synthesis.sqlite3", "LOOPOVER_MINER_DENY_HOOK_SYNTHESIS_DB", env),
84+
);
85+
}
6986
});
7087
});
7188

test/unit/miner-laptop-init.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,23 @@ afterEach(() => {
5454
describe("loopover-miner laptop init (#2329)", () => {
5555
it("resolves the laptop SQLite path from the state-dir override and XDG fallback", () => {
5656
expect(resolveLaptopStateDbPath({ LOOPOVER_MINER_CONFIG_DIR: "/custom/state" }))
57-
.toBe("/custom/state/laptop-state.sqlite3");
57+
.toBe(join("/custom/state", "laptop-state.sqlite3"));
5858
expect(resolveLaptopStateDbPath({ XDG_CONFIG_HOME: "/xdg" }))
59-
.toBe("/xdg/loopover-miner/laptop-state.sqlite3");
59+
.toBe(join("/xdg", "loopover-miner", "laptop-state.sqlite3"));
6060
});
6161

6262
it("falls back to ~/.config when neither LOOPOVER_MINER_CONFIG_DIR nor XDG_CONFIG_HOME is set", () => {
6363
expect(resolveLaptopStateDbPath({})).toBe(join(homedir(), ".config", "loopover-miner", "laptop-state.sqlite3"));
6464
});
6565

66+
it("honors LOOPOVER_MINER_LAPTOP_STATE_DB over config-dir and XDG fallbacks (#8336)", () => {
67+
expect(resolveLaptopStateDbPath({
68+
LOOPOVER_MINER_LAPTOP_STATE_DB: "/custom/laptop-state.sqlite3",
69+
LOOPOVER_MINER_CONFIG_DIR: "/custom/state",
70+
XDG_CONFIG_HOME: "/xdg",
71+
})).toBe("/custom/laptop-state.sqlite3");
72+
});
73+
6674
it("fresh init creates the state dir and SQLite file", () => {
6775
const root = tempRoot();
6876
const env = { LOOPOVER_MINER_CONFIG_DIR: join(root, "state") };

test/unit/miner-orb-export.test.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { mkdtempSync, rmSync } from "node:fs";
2-
import { tmpdir } from "node:os";
2+
import { homedir, tmpdir } from "node:os";
33
import { join } from "node:path";
44
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
55

@@ -19,6 +19,7 @@ import {
1919
sendAmsExportBatch,
2020
} from "../../packages/loopover-miner/lib/orb-export.js";
2121
import type { OrbExportOutcome, OrbExportRow } from "../../packages/loopover-miner/lib/orb-export.js";
22+
import { resolveLocalStoreDbPath } from "../../packages/loopover-miner/lib/local-store.js";
2223

2324
let dir: string;
2425
function storePath() {
@@ -210,10 +211,28 @@ describe("resolveOrbExportDbPath (#4277)", () => {
210211
it("resolves the DB path from env override, miner config dir, XDG config, then the home default", () => {
211212
expect(resolveOrbExportDbPath({ LOOPOVER_MINER_ORB_EXPORT_DB: "/custom/d.sqlite3" })).toBe("/custom/d.sqlite3");
212213
expect(resolveOrbExportDbPath({ LOOPOVER_MINER_CONFIG_DIR: "/custom/config" })).toBe(
213-
"/custom/config/orb-export.sqlite3",
214+
join("/custom/config", "orb-export.sqlite3"),
214215
);
215-
expect(resolveOrbExportDbPath({ XDG_CONFIG_HOME: "/xdg" })).toBe("/xdg/loopover-miner/orb-export.sqlite3");
216-
expect(resolveOrbExportDbPath({})).toMatch(/\/\.config\/loopover-miner\/orb-export\.sqlite3$/);
216+
expect(resolveOrbExportDbPath({ XDG_CONFIG_HOME: "/xdg" })).toBe(
217+
join("/xdg", "loopover-miner", "orb-export.sqlite3"),
218+
);
219+
expect(resolveOrbExportDbPath({})).toBe(
220+
join(homedir(), ".config", "loopover-miner", "orb-export.sqlite3"),
221+
);
222+
});
223+
224+
it("stays byte-identical to resolveLocalStoreDbPath for representative env combinations (#8336)", () => {
225+
const cases: Array<Record<string, string | undefined>> = [
226+
{ LOOPOVER_MINER_ORB_EXPORT_DB: "/custom/d.sqlite3" },
227+
{ LOOPOVER_MINER_CONFIG_DIR: "/custom/config" },
228+
{ XDG_CONFIG_HOME: "/xdg" },
229+
{},
230+
];
231+
for (const env of cases) {
232+
expect(resolveOrbExportDbPath(env)).toBe(
233+
resolveLocalStoreDbPath("orb-export.sqlite3", "LOOPOVER_MINER_ORB_EXPORT_DB", env),
234+
);
235+
}
217236
});
218237
});
219238

0 commit comments

Comments
 (0)