Task: Supply connections.db master password via CLI arg or .env

Table of Contents

This page documents a task in the Automate connections.db master-password unlock via CLI/env story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Add a --master-password CLI arg and ORES_CONNECTIONS_MASTER_PASSWORD env var (CLI wins, mirroring the existing instance-name=/=env-type pattern in CommandLineParser), and wire MainWindow::initializeConnectionManager() to attempt verification with the supplied value before falling back to MasterPasswordDialog. A failed auto-unlock attempt must show a clear, loud message rather than silently falling through or proceeding unlocked; the manual dialog stays available when nothing is supplied.

Status

Field Value
State DONE
Parent story Automate connections.db master-password unlock via CLI/env
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-29

Acceptance

  • [X] --master-password CLI arg and ORES_CONNECTIONS_MASTER_PASSWORD env var both supply the master password (CLI wins).
  • [X] When supplied, initializeConnectionManager() attempts unlock with it before falling back to MasterPasswordDialog – no dialog shown if it succeeds.
  • [X] A failed auto-unlock attempt shows a clear message box stating unlock was attempted automatically from the environment/CLI and failed, then falls through to the interactive Unlock dialog rather than silently proceeding unlocked.
  • [X] Manual MasterPasswordDialog (Unlock=/=Create=/=Change) is unaffected when no env/CLI value is supplied.

Plan

  • CommandLineParser: added --master-password option and a masterPassword() accessor, mirroring openScenario()=/=envType().
  • main.cpp: resolves CLI arg -> ORES_CONNECTIONS_MASTER_PASSWORD env var (same precedence pattern as instanceName=/=envType), passes the result to MainWindow's constructor as a new cliMasterPassword parameter (following the existing openScenarioPath constructor-param precedent – needed at construction time, not via a setter, since initializeConnectionManager() can run before any caller-supplied setter would fire).
  • MainWindow::initializeConnectionManager(): if masterPassword_ is empty and a CLI/env password was supplied, try it first (autoUnlockAttempted flag). On verification failure specifically from that auto-unlock attempt, show a distinct "Auto-Unlock Failed" message box, clear masterPassword_, then fall through into the existing Unlock dialog flow unchanged.
  • No new unit test: MainWindow has no existing unit-test harness (Qt widget, exercised via manual QA/screenshots per the * Test Scenarios table below); local build (ores.qt.exe) and the existing ores.qt.tests=/=ores.qt.headless.tests suites both pass.
  • After manual verification (below), added explicit INFO-level logging around the auto-unlock attempt/success in initializeConnectionManager(), so a support/debug session can confirm from the log alone that auto-unlock fired and succeeded, not just infer it from the absence of a dialog.
  • Extended compass client start (compass_services.py) with a --master-password passthrough flag, mirroring --open-scenario. ORES_CONNECTIONS_MASTER_PASSWORD itself needed no compass code change: Ctx.child_env() already merges every .env var into the launched process's environment, so qgetenv() picks it up for free once the var exists in .env.
  • env_init.py: added an always-emitted (blank-by-default, preserved-if-set) ORES_CONNECTIONS_MASTER_PASSWORD block to the generated .env, so every environment discovers the var rather than only ones that opt in by hand. Bumped .env format version to 16 (compass env version new) and regenerated this environment's .env to confirm the value survives regeneration.

Notes

Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario, run through the QA Validation Runner panel) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
Manual: launched compass client start with ORES_CONNECTIONS_MASTER_PASSWORD set in .env to the real configured master password; confirmed no MasterPasswordDialog prompt appeared and the log showed the attempt/success lines. Verified Run by Marco directly (not scripted as a test_scenario doc – would require a live master-password-protected connections.db, which is real user data, not synthetic fixture data).

PRs

PR Title
#1739 [ores.qt] Supply connections.db master password via CLI arg or .env

Review

# Comment summary File Decision Notes
1 cliMasterPassword_ not cleared on failed auto-unlock, causing the same bad password to be retried and re-warned on a later initializeConnectionManager() call MainWindow.cpp Fixed Clear cliMasterPassword_ alongside masterPassword_ on failure.
2 connections/master_password_configured not set when auto-unlock succeeds trivially on a fresh DB with no encrypted passwords yet MainWindow.cpp Fixed Set the QSettings flag in the autoUnlockAttempted success branch too, matching the Create dialog path.
3 –master-password CLI arg visible in process listing (ps/proc); recommend the env var instead CommandLineParser.cpp Fixed Added a one-line callout to the –help text.
4 QString::fromLatin1(qgetenv(…)) mangles non-ASCII env values main.cpp Declined Matches the existing convention already used for ORES_CHECKOUT_LABEL/ORES_ENV_TYPE in the same file; out of scope for this task to change project-wide.
5 env_init.py writes the value unquoted; load_env()'s strip() would trim leading/trailing whitespace on regeneration env_init.py Declined Matches every other simple var in the same generator (e.g. ORES_DB_COMPUTE_WRAPPER_USER); unlikely edge case, not specific to this var.

Result

ores.qt now accepts the connections.db master password via --master-password or ORES_CONNECTIONS_MASTER_PASSWORD, tried non-interactively before MasterPasswordDialog in initializeConnectionManager(). A wrong supplied password shows an explicit "Auto-Unlock Failed" message box and falls through to the normal interactive Unlock dialog; nothing changes when no env/CLI value is supplied. Local build (ores.qt.exe) and ores.qt.tests=/=ores.qt.headless.tests both pass.

Manually verified end-to-end against a real connections.db: set ORES_CONNECTIONS_MASTER_PASSWORD in .env, launched via compass client start, confirmed no dialog appeared and the log showed both "Attempting connections.db auto-unlock…" and "…auto-unlocked successfully via CLI/env master password" at INFO level.

Review round 1 (four independent passes) confirmed the core implementation is sound and caught two real edge cases, both fixed: a failed auto-unlock left the bad password sitting in cliMasterPassword_, so a later call could retry it and re-show the warning; and a fresh, empty connections.db (where verify_master_password() trivially passes) skipped marking the master password as configured, which would have re-triggered the "Create" dialog on a later launch without the CLI/env value. Also added a --help callout recommending the env var over the CLI flag (process-listing visibility). Declined two nits as pre-existing, codebase-wide conventions rather than defects specific to this task (see * Review table).

Also extended compass client start with a --master-password passthrough and env_init.py's generated .env with the new var (blank by default, preserved if set; .env format version bumped to 16), so every environment picks up the feature without hand-editing .env.

Emacs 29.3 (Org mode 9.6.15)