Skip to content

engine: vault choice is NOT remembered across launches — restored string path crashes store-path RPC (path->string contract violation), wedging the UI; contradicts the documented "remembered across launches" #6

Open

Description

@turinglambdaai

Context

Cross-platform consistency pass of the v0.2.0 release (Linux arm64 deb on Ubuntu 26.04 VM; the failing code is the shared engine, so all three platforms are affected). The no-vault splash promises "The choice is remembered across launches." — the packaged release does the opposite.

Repro (v0.2.0 Linux deb, deterministic)

  1. Fresh install, launch → "No vault selected" (works).
  2. Choose Vault… → pick any secrets.ini → vault loads, "Store switched: …" in the status line. At this point ~/.keyward/config.json contains {"store":"/…/demo-vault.ini"} (written by store-open, app/backend.rkt:50).
  3. Quit and relaunch.
  4. Within seconds-to-minutes a raw "Engine message" dialog appears:
    path->string: contract violation
      expected: path?
      given: "/home/turinglambdaai/keyward-test/vault/demo-vault.ini"
    
  5. After Close, the UI stays on "Starting embedded Racket CS…" indefinitely; sidebar shows Products 0 and the Choose Vault… button never returns. The instance is wedged until killed; deleting ~/.keyward/config.json restores the first-launch state (verified recovery path).

Root cause (v0.2.0 tag, app/backend.rkt)

current-store is declared "a path string, or #f" (line 30) and restored as a string from config at startup (line 32 via store-path-default). But store-open puts a path object into the parameter (line 47: (current-store p) where p comes from simple-form-path), and the store-path RPC then unconditionally does (path->string p) (line 42) — a contract violation on the restored-string case, raised inside the RPC thread at startup and surfaced as the raw Engine message. The type of current-store differs depending on whether the vault was opened live or restored.

Suggested fix (two lines, shared engine)

Keep the declared string invariant:

  • line 47: (current-store (path->string p))
  • line 42: (if p p "")

Everything downstream (store-sections, file->lines, …) already accepts path strings.

Found via the vmpal-consistency three-platform pass; happy to send the short-lived-branch PR immediately if you confirm.

Activity

  1. turinglambdaai commented on Oct 27, 2026

    @turinglambdaai
    OwnerAuthor

    Update: main (ae8a1d2, #5) already carries the end-to-end string invariant with a defensive cond in store-path — the two-line fix I sketched is superseded. What's broken is the shipped v0.2.0 (tag 0021e35 predates #5): every v0.2.0 install bricks its second launch the moment a vault is chosen, and the USER-GUIDE "Known limits" section only hints at "release evidence pending".

    Actionable ask: cut the next patch release from main ASAP, and consider a release-note line telling v0.2.0 users to delete ~/.keyward/config.json once before upgrading (the wedged state survives until then). The repro above should fold into the release-acceptance checklist — a restart-after-select step would have caught it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions