Files
relicario/docs/superpowers/coordination/v0.9.0-dev-e-resume.md

5.5 KiB

Dev E — RESUME Prompt (v0.9.0 Plan 5, keyfile extension + positioning)

Paste everything below the --- into a fresh Claude Code terminal.


You are RESUMING Plan 5 (keyfile extension + positioning pivot) for v0.9.0. The lift paused ~21h ago; you are a fresh session with no relay history. Your worktree, branch, and commits already exist — do NOT recreate the worktree and do NOT restart from Task 1.

You are UNBLOCKED: Dev-D (keyfile core/cli/wasm) is MERGED to main — the real WASM bindings are available now.

Resume setup (replaces the original Setup block)

cd /home/alee/Sources/relicario.v0.9.0-dev-e
pwd                       # must print /home/alee/Sources/relicario.v0.9.0-dev-e
git status
git log --oneline -6      # confirm Task 1 (wizard) + Task 6 (docs) + scaffold are committed (down to c79ff1c)
git fetch origin
git merge origin/main     # PULLS IN Dev-D's keyfile WASM bindings (keyfile_encode/decode, unlock_with_secret)
                          # + the SecondFactor params hint. Resolve any trivial wasm.d.ts conflicts (keep both).

ALL work stays in /home/alee/Sources/relicario.v0.9.0-dev-e. Every subagent prompt MUST start with cd /home/alee/Sources/relicario.v0.9.0-dev-e.

Read for full context

  • docs/superpowers/coordination/v0.9.0-dev-e-prompt.md — your ORIGINAL prompt: ROLE, RELAY protocol + shim, STATUS/QUESTION formats, polling cadence, specs/plan paths. IGNORE its Setup block and "begin Task 1."
  • docs/superpowers/plans/2026-06-20-v0.9.0-keyfile-ext-positioning.md — your plan.
  • CLAUDE.md.

Relay up on localhost:7331 (shim: cd /home/alee/Sources/relicario/tools/relay && python3 call.py read_messages '{"for":"dev-e"}'). PM is live — poll before/after every subagent + at task boundaries.

WHERE YOU ARE — already done, do NOT redo (commits, local-only)

  • Task 1 wizard second-factor choice (Reference Image | Key File) — DONE.
  • Task 6 positioning docs (README re-lead on the two-factor-KDF thesis; stego framed as one option) — DONE (1591fc7..9e19949). Will need reconciliation with the FORMATS/SECURITY deltas below.
  • Scaffold types committed (create_vault secondFactor request + relkeyBytes response) — c79ff1c.

KEY FACTS from Dev-D (now on main — authoritative)

  • WASM: keyfile_encode(Uint8Array)->Uint8Array, keyfile_decode(Uint8Array)->Uint8Array (throws on bad armor/length), unlock_with_secret(passphrase:string, secret:Uint8Array[32], salt:Uint8Array[32], params_json:string)->SessionHandle.
  • Pass the SAME params_json you already give unlock()second_factor does NOT affect the KDF (that is the equivalence guarantee; D's test proves byte-identical master keys).
  • params.json is a nested ParamsFile wrapper; second_factor is a TOP-LEVEL field on it (image|keyfile, absent ⇒ image). Read it pre-unlock to pick the image-picker vs key-file-picker.
  • Armor: relicario-keyfile-v1\n + base64(32 bytes) + \n; ext .relkey; the secret is IN THE CLEAR.

YOUR REMAINING WORK (you merge after D — which is done — so you can REVIEW-READY as soon as you're complete)

  • Task 2 SW create_vault key-file branch: generate the 32-byte secret (crypto.getRandomValues), unlock_with_secret, write params.json second_factor: "keyfile", store keyfileBase64 in chrome.storage.local (exactly like imageBase64), return { relkeyBytes } (base64-enveloped via shared/message-binary.ts).
  • Task 3 wizard key-file download: trigger a vault.relkey download from the create_vault response + "save this key file" copy.
  • Task 4 SW unlock branches on the params hint: if keyfile, load keyfileBase64keyfile_decodeunlock_with_secret; else the image path. Malformed → invalid_key_file.
  • Task 5 attach-mode key-file picker: detect second_factor in the probe; render a .relkey input when keyfile; store keyfileBase64; verify via unlock_with_secret.
  • Doc deltas to LAND (Dev-D deliberately left these to you — reconcile with your Task 6): FORMATS.md (.relkey armor relicario-keyfile-v1 + base64(32) + the params top-level second_factor), SECURITY.md (.relkey / keyfileBase64 is the second factor IN THE CLEAR, gitignored + never pushed on CLI, local-only in chrome.storage on the extension — server only ever sees opaque ciphertext; same posture as the reference JPEG, NOT encrypted), docs/CRYPTO.md (pluggable-transport framing), docs/user_docs/ if any extension-facing keyfile usage.
  • Verify the extension recovery-QR works for a key-file vault — it should already work because unlock_with_secret stores the secret in the WASM session and generate_recovery_qr reads from the session (NOT re-resolved from imageBase64); confirm it does not assume an image. If it re-resolves from the image, fix it.
  • MANDATORY /security-review on the key-file path before REVIEW-READY (equivalence-to-stego, armor parsing, in-the-clear-storage honesty, no oracle difference). Binary crosses chrome.runtime.sendMessage base64-enveloped only.
  • Then full validation (cd extension && npx vitest run && npm run build:all), simplify pass, push feature/v0.9.0-dev-e-keyfile-ext, post Status: REVIEW-READY.

First action

cd into the worktree, git log --oneline -6, read_messages(for="dev-e") for my resume directive, post a ## STATUS UPDATE (Status: IN-PROGRESS, Task: 2 create_vault keyfile) confirming RESUMED + main merged + D bindings present, then continue via superpowers:subagent-driven-development.