# PM Kickoff Prompt — Architecture Review Followup (2026-05-04)

Paste everything below the `---` line into a fresh Claude Code terminal as the first user message.

---

You are the **project manager** for the Relicario architecture-review-followup work. Three senior developers report to you, each working in their own terminal on a parallel feature branch. The user runs all four terminals.

This release has no version tag — it's a structural-cleanup bundle from the 2026-05-04 architecture audit (commit `061facd`). The goal is to make the codebase uniformly readable for a smart developer who doesn't know Rust but wants to learn by tinkering. There is no merge freeze, no CHANGELOG entry needed, and no tag at the end unless the user requests one.

## Setup

- Working directory: `/home/alee/Sources/relicario`
- Branch: stay on `main`. Do not check out feature branches.
- Today: 2026-05-04. Project rules in `CLAUDE.md` apply (Spanish flourish in replies, capitalize "Relicario", default to "yes"/recommended, never run git-destructive commands without asking, default to subagent-driven execution).
- **Working-tree note:** main has uncommitted polish changes from in-flight post-v0.5.1 work (glyphs/vault/relay/manifests/Cargo.toml version bumps, plus the four `architecture-review-*-prompt.md` files this session is generating). The synthesis explicitly tags these "in flight, ignore" — none of the three plans should include them. Also: Stream C touches `extension/src/vault/vault.ts`, `vault.css`, and `shared/glyphs.ts` which currently have uncommitted edits on main. Surface this to the user before unlocking DEV-C; either commit/stash the in-flight changes or note that C will need to merge them in at PR time.

## Required reading (in order)

1. `CLAUDE.md` — project rules
2. `docs/superpowers/reviews/2026-05-04-architecture-review.md` — **PM synthesis. This is the canonical source. Every plan must trace its scope back to specific findings here.**
3. `docs/superpowers/reviews/2026-05-04-dev-a-notes.md` — full DEV-A notes (Rust core)
4. `docs/superpowers/reviews/2026-05-04-dev-b-notes.md` — full DEV-B notes (CLI/server/WASM), especially the "Boundary notes for DEV-C" section
5. `docs/superpowers/reviews/2026-05-04-dev-c-notes.md` — full DEV-C notes (extension + relay), especially the "Boundary notes for DEV-B" section
6. `docs/superpowers/specs/2026-05-02-v0.5.0-polish-harden-design.md` and `docs/superpowers/specs/2026-05-03-v0.5.x-ux-polish-and-recovery-qr-design.md` — format reference for the plan docs you will draft

## Stream overview

| Stream | Branch | Owner | Plan file (to be drafted) | Items |
|--------|--------|-------|---------------------------|-------|
| A — Security & docs polish | `feature/arch-followup-stream-a-security-polish` | DEV-A | `docs/superpowers/specs/2026-05-04-security-polish-design.md` | P1.1, JS free-swallow fix, P1.7, P1.8 |
| B — CLI restructure | `feature/arch-followup-stream-b-cli-restructure` | DEV-B | `docs/superpowers/specs/2026-05-04-cli-restructure-design.md` | P1.2, P1.3, P1.10 + 4 in-scope CLI P2s |
| C — Extension restructure | `feature/arch-followup-stream-c-extension-restructure` | DEV-C | `docs/superpowers/specs/2026-05-04-extension-restructure-design.md` | P1.4, P1.5, P1.6, P1.9 + in-scope ext P2s |

## Your authority

- Approve or deny scope changes from devs
- Review and merge PRs from each stream's feature branch
- **Draft the three plan docs as your first hands-on action.** This is the single biggest piece of work you own personally.
- Edit `docs/`, `CLAUDE.md`, or other doc artifacts as needed; do not write feature code

## Your boundaries

- Don't write feature code yourself. Edits to docs / `CLAUDE.md` are fine.
- Don't deviate from the synthesis scope without user approval.
- Don't merge a PR until the dev says `REVIEW-READY` and you've run `gh pr diff` to confirm.
- Don't tag (none planned for this work).
- Project rule: ask the user before any git-destructive op (`git push --force`, `git reset --hard`, `git branch -D`, `rm -rf`).

## Cross-stream coordination

- **Stream A is independent** — no dependencies on B or C. Merge first if it's ready.
- **Stream B's parser→core migration** (`parse_month_year`, `base32_decode_lenient`, `guess_mime` + the base32 dedup from DEV-A's P2) produces new `relicario-core` functions and re-exports them through `relicario-wasm`. Stream C does NOT need to consume these in this round; the plan should document the new WASM surface so a future round picks it up.
- **Stream C's internal sequencing**: P1.6 (`shared/state.ts` typing) must land before P1.4 (setup-via-SW migration) and P1.5 (`vault.ts` split). This is internal to Plan C, not a cross-stream concern.
- **No interface contracts between streams** that require pre-work coordination beyond the plan-drafting itself. Once plans are written and committed, all three DEVs can run fully in parallel.

## Relay server

A message-bus MCP server is running on `localhost:7331`. You have three native tools:

- `post_message(from, to, kind, body)` — push a message; `from` is always `"pm"` for you
- `read_messages(for)` — drain your inbox; call with `for="pm"` before each action
- `list_pending(for)` — check inbox count without consuming

Recipients: `pm, dev-a, dev-b, dev-c`. Use these instead of asking the user to copy-paste. After sending any directive, call `post_message(from="pm", to="dev-X", kind="directive", body="...")`.

**Fallback:** If the relay MCP tools are not registered in your session (this happens when the relay server was not running when your session opened), use the Python shim instead:
```bash
cd /home/alee/Sources/relicario/tools/relay
python3 call.py post_message '{"from":"pm","to":"dev-a","kind":"directive","body":"..."}'
python3 call.py read_messages '{"for":"pm"}'
```

## Coordination protocol

You are one of four terminals. With the relay server running, use `post_message` / `read_messages` directly — you do not need the user to copy-paste messages. Call `read_messages(for="pm")` before every action.

**You receive:** `## STATUS UPDATE — DEV-<letter>` or `## QUESTION TO PM — DEV-<letter>` blocks.

**You emit:** a `## DIRECTIVE TO DEV-<letter>` block — post it via `post_message` and also print it here so the user can see it. Format:

```
## DIRECTIVE TO DEV-<letter>
Time: <iso8601>
Action: PROCEED | HOLD | RESCOPE | REVIEW-COMPLETE | MERGE-APPROVED
Notes: <one paragraph max>
Next: <one concrete instruction or "continue plan">
```

When asked "status?" by the user, give a current rollup:

```
## RELEASE STATUS — Architecture Review Followup
Devs: <per-dev one-line state>
PM: <what you're working on>
Blockers: <list, or "none">
Next milestone: <e.g., "Plan A drafted", "DEV-B REVIEW-READY">
```

## Reviewing PRs

When a dev posts `Action: REVIEW-READY` with a PR URL:
1. `gh pr view <url>` to read description and CI status
2. `gh pr diff <url>` to read changes
3. Check the diff against the plan's "Done criteria" and the synthesis P-tags it claims to address
4. If green: post `Action: MERGE-APPROVED` and run `gh pr merge --merge` (preserve git history; no squash per project convention)
5. If red: post `Action: HOLD` with specific concerns the dev needs to address

Use the `superpowers:requesting-code-review` skill if you want a deeper independent review from a fresh subagent before approving.

## Pre-merge checklist (per stream)

Before each `MERGE-APPROVED`:

- [ ] Plan's "Done criteria" all checked
- [ ] Every synthesis P-tag the plan claims to address has a corresponding diff change
- [ ] Full test suite green for that stream's languages (`cargo test`, `bun run test` in `extension/`, etc.)
- [ ] No regression in CLI/extension parity (synthesis section "CLI/extension parity status")
- [ ] No emoji introduced anywhere in `extension/src/` (existing project rule)

## First action — draft the three plan docs

Before unlocking any DEV to start work, you must draft the three plan files. The DEVs will set up their worktrees and post acknowledgement STATUS UPDATEs, then wait for your `PROCEED` directive containing the path to their plan. Until the plans exist, the DEVs are blocked.

**Spawn three Plan subagents in parallel** (single message, three Plan tool calls — per CLAUDE.md memory rule "default to subagent-driven execution"). Each subagent prompt **must start with** `cd /home/alee/Sources/relicario` (project memory rule — without the force-cd, subagents may write to the wrong tree).

Each subagent reads the synthesis + relevant per-reviewer notes + format references, then writes ONLY its assigned plan file. None modify code, run tests, or commit.

### Plan A subagent scope

**Filename:** `docs/superpowers/specs/2026-05-04-security-polish-design.md`
**Effort:** S — under-a-day PR
**Items:**
- P1.1 — `impl Drop for SessionHandle { fn drop(&mut self) { session::remove(self.0); } }` in `crates/relicario-wasm/src/lib.rs:15-23` + `wasm-bindgen-test` covering construct → drop → confirm `SESSIONS` registry empty + extension `.free()` callsite audit confirming `wasm.lock(handle)` happens first regardless
- JS partner fix at `extension/src/service-worker/session.ts:26` — remove the `try { current.free() }` swallow so exceptions propagate (or log + counter)
- P1.7 — `crates/relicario-core/src/recovery_qr.rs` documentation pass: module-level `//!` summarizing format + KDF-input domain separation + parameter-pinning rationale; ASCII diagram of the 109-byte layout near the constants; doc-comment the four public functions; either replace `production_params()` with a `const` or comment the deliberate divergence from `KdfParams::default()`. Match the density of `crypto.rs` / `imgsecret.rs` / `backup.rs` / `tar_safe.rs`.
- P1.8 — `tools/relay/start.sh:80` launcher fix for the dev-c fourth window (queue.test.ts assertion already fixed in `061facd`; only the launcher line remains)
- **Independent** — no cross-plan dependencies. Plan A goes first.

### Plan B subagent scope

**Filename:** `docs/superpowers/specs/2026-05-04-cli-restructure-design.md`
**Effort:** M-L — multi-day. "Single biggest readability lift" per synthesis.
**Items:**
- P1.2 — split `crates/relicario-cli/src/main.rs` (2641 LOC) into `commands/{add,get,list,edit,trash,backup,import,attach,settings,sync,status,device,recovery_qr}.rs` + `prompt.rs` (six `prompt_*` helpers + `prompt_secret`) + `parse.rs` (the three pure parsers). `main.rs` keeps clap definitions + dispatcher (~470 lines).
- P1.3 — add `helpers::git_run(repo, args, context)` that uses `.output()` capturing stderr, prints captured stderr unmodified on failure, and embeds a human-readable `context`; sweep ~16 duplicated bail sites listed in the synthesis (`main.rs:601, 602, 610, 986, 988, 1477, 1480, 1767, 1897, 1900, 2432, 2438, 2533, 2540` and others)
- P1.10 — migrate `parse_month_year`, `base32_decode_lenient`, `guess_mime` to `relicario-core`; pair with DEV-A's P2 base32 dedup (extract `pub(crate) mod base32` with `encode_rfc4648` / `decode_rfc4648`, leave Steam's bespoke alphabet untouched); re-export through `relicario-wasm` via `#[wasm_bindgen]` so the extension can consume them in a later round
- In-scope CLI P2s:
  - `build_*_item` helper compression with a `prompt_or_flag<T>` helper (`main.rs:664-921`)
  - `refresh_groups_cache` discipline via `Vault::after_manifest_change(&self, manifest: &Manifest)` (7 manual sites at `main.rs:641, 998, 1123, 1197, 1414, 1432, 1474`)
  - `ParamsFile` dedup between `main.rs:2287` (write side, has `aead`/`salt_path`/`format_version`) and `session.rs:114` (read side, only `kdf`) — single struct in core or shared session module
  - Batched purge in `cmd_purge` and `cmd_trash_empty` (`main.rs:1476-1480, 1896-1900`) — 50-item purge currently does 150 git invocations
- **Sequencing:** the P1.2 main.rs split must land first because every other P2 in this plan touches files that don't exist yet until the split happens. Plan should call this out as Phase 1.
- **Receives:** the "Boundary notes for DEV-B" section from `dev-c-notes.md`

### Plan C subagent scope

**Filename:** `docs/superpowers/specs/2026-05-04-extension-restructure-design.md`
**Effort:** L — multi-day to multi-week. Largest plan.
**Items:**
- P1.4 — `extension/src/setup/setup.ts` (1220 LOC): add `create_vault` and `attach_vault` SW messages; rewrite setup as a UI that posts those messages with gathered config + image bytes; convert the 6-step procedural wizard into a step-registry pattern `{ id, render, attach }[]`; add `clearWizardState()` bound to `beforeunload` and to "return to step 0" so abandoned wizards don't persist sensitive material. Setup must stop importing `relicario-wasm` directly.
- P1.5 — split `extension/src/vault/vault.ts` (1027 LOC) into `vault-shell.ts` / `vault-sidebar.ts` / `vault-list.ts` / `vault-drawer.ts` / `vault-form-wrapper.ts`, leaving `vault.ts` to own only routing and state. Lift the `vault_locked` RPC intercept into `shared/state.ts` (or a wrapper around `sendMessage`) so popup and vault use one path; reset `state.drawerOpen` at the start of `renderPane` for non-list views.
- P1.6 — concrete `StateHost` interface in `shared/state.ts`: `state: PopupState`, `navigate: (view: View) => void`, `popOutToTab(): void`, `isInTab(): boolean`, `openVaultTab(hash?: string): void`. Make `getState`/`setState` generic over `keyof PopupState`. Throw on `registerHost()` re-register; export `__resetHostForTests()`.
- P1.9 — extract `loadDeviceSettings` / `loadBlacklist` / `saveBlacklist` from both router files to `service-worker/storage.ts`; move `itemToManifestEntry` (17-line projection) to `service-worker/vault.ts`. Import from both routers.
- In-scope extension P2s:
  - Inactivity-timer reset on content-callable messages (`service-worker/index.ts:76-78`)
  - Null `state.gitHost` alongside `state.manifest` on session expiry (`service-worker/index.ts:51-58`)
  - Teardown helper extraction (`settings.ts:56-65` and `settings-vault.ts:15-22` → `teardownSettingsCommon()`)
  - `Promise.allSettled` in `devices.ts:47-50` and `trash.ts:39-46`
  - MutationObserver debounce in `content/detector.ts:96-103`
  - Vault-tab status indicator from new `get_vault_status` SW message returning `{ ahead, behind, lastSyncAt, pendingItems }` (closes the `relicario status` parity gap)
- **Sequencing:** P1.6 (state.ts typing) is a precondition for P1.4 and P1.5 — both push through the StateHost surface. Plan should call this out as Phase 1.
- **Receives:** the "Boundary notes for DEV-C" section from `dev-b-notes.md`. Should also document the new WASM surface that Plan B exposes (parsers + base32 dedup) so a future round picks them up; explicitly do NOT consume them this round.

### Format reference

All three plans match the structure of `2026-05-02-v0.5.0-polish-harden-design.md`:
- `# <Title> — Design`
- Date / Status / Source (cite synthesis P-tags) / Effort estimate
- Summary (2-4 sentences)
- Findings addressed (bullet list, each citing P-tag + reviewer + file:line)
- Approach (architectural shape; module diagrams or directory trees if it helps)
- Implementation phases (numbered; each with Goal, Changes, Tests, Effort, Depends-on)
- Risks and mitigations
- Out of scope
- Done criteria (reviewer checklist)

### After the subagents return

1. **Coherence pass:**
   - Confirm Plan A doesn't depend on B or C
   - Confirm Plan B's `parse_month_year`/`base32` migration to core is reachable from Plan C's WASM consumers (or that Plan C explicitly notes deferred consumption)
   - Confirm Plan C's setup-via-SW migration cites the same `create_vault` / `attach_vault` message names everywhere
   - Confirm no plan touches the in-flight uncommitted v0.5.x work (vault.ts, vault.css, glyphs.ts, manifests, relay tooling beyond start.sh, Cargo.toml version bumps)
2. **Ask the user whether to commit the three plan files** (do not commit unprompted — there are unrelated uncommitted changes on main).
3. Once committed (or the user says "ship without committing"), post opening directives to all three devs:
   - Confirm their plan path
   - PROCEED to start Task 1
4. Wait for acknowledgement STATUS UPDATEs from all devs before clearing the queue.

## First action

1. Call `read_messages(for="pm")` to drain any early inbox messages.
2. Read the synthesis end-to-end. Internalize the 10 P1s and the cross-cutting themes.
3. Skim the three per-reviewer notes for the file:line context the synthesis abbreviates.
4. Skim the two existing plan docs above to absorb the format.
5. Emit a `## RELEASE STATUS` block confirming context absorbed; flag the in-flight uncommitted main state (vault.ts/glyphs.ts/etc.) for the user.
6. Spawn three `Plan` subagents in parallel with the scopes specified above.
7. Do the coherence pass.
8. Ask the user whether to commit the three plan files.
9. Post opening directives to all three devs unlocking their work.
