Rewrite as user-agnostic "quicksilver" plugin

Rename echo-memory/ECHO -> quicksilver/Quicksilver throughout and make the
plugin self-configuring per operator:

- First-run flow: prompt for endpoint FQDN, API key, and operator name/role;
  verify; persist to a local config file (~/.quicksilver/quicksilver-config.json).
- Two-layer setup detection: local config (is this install configured?) +
  in-vault marker (is the vault scaffolded?). Key never stored in the vault.
- Replace hardcoded endpoint/key in all curl examples with $BASE/$AUTH loaded
  from the config file.
- Genericize all "Jason"/"Bryan goldbrain"/MPM/wISP references to "the operator";
  keep Jason as architect credit (README + plugin.json author).
- Personalize memory to the configured operator (name/role seeded into
  operator-preferences and the vault marker).
- Add echo-vault.md -> quicksilver-vault.md rename migration.
- Rebuild packaged quicksilver.plugin; add docs/quicksilver-plan.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jason
2026-06-07 08:06:51 -05:00
parent 3ba73b2d48
commit d90abde29e
25 changed files with 400 additions and 167 deletions
+140
View File
@@ -0,0 +1,140 @@
# Quicksilver — user-agnostic rewrite + rename plan
## Objective
Turn the plugin (formerly `echo-memory` / "ECHO") into one a coworker can install
cold. On first run it detects it's freshly installed, prompts for the **API endpoint
FQDN**, **API key**, and **operator name/role**, verifies them, persists them to a
**local bootstrap indicator file**, then bootstraps the vault and personalizes memory
to that operator. The system is renamed to **Quicksilver** throughout. Jason stays
credited only as the architect.
## Locked decisions
1. **Credentials** → a dedicated **local bootstrap indicator file** (client-side) holds
FQDN + API key. The in-vault marker stays a pure schema/version flag (no secret).
2. **Operator identity** → prompt for name/role at first run; personalize memory
("Alex prefers X"); seed `operator-preferences.md` + the marker with it.
3. **Attribution** → Jason kept in `plugin.json` `author` + a one-line
"Architecture by Jason Stedwell" credit in the README. Every other operational
mention removed.
4. **Name** → full rename `echo-memory` / `ECHO``quicksilver` / `Quicksilver`
(0 "echo" hits after the pass).
## Core design: two-layer "is this set up?" detection
| Layer | File | Question | Holds |
|---|---|---|---|
| 1. Local indicator (new) | `~/.quicksilver/quicksilver-config.json` (client-side) | "Is *this install* configured?" | FQDN + **API key** + operator name/role |
| 2. Vault marker (existing) | `_agent/quicksilver-vault.md` (in vault) | "Is the *vault* scaffolded?" | schema_version, bootstrap date, operator name — **never the key** |
The secret lives client-side (you need it *before* you can reach the vault, and the
plugin's own safety rule forbids keys in vault notes). The vault marker stays a pure
schema flag. The local indicator file *is* the "freshly installed?" signal — its
absence triggers first-run.
### Local indicator file spec
Path: `~/.quicksilver/quicksilver-config.json` (Windows:
`%USERPROFILE%\.quicksilver\quicksilver-config.json`). Lives in the user home, **not**
the plugin dir, so it survives plugin reinstalls/updates.
```json
{
"schema": 1,
"endpoint": "https://<operator-fqdn>",
"api_key": "<bearer-token>",
"operator": { "name": "Alex Rivera", "role": "Network Engineer" },
"configured_at": "2026-06-07",
"verified_at": "2026-06-07"
}
```
The skill reads this with the Read tool at session start and substitutes
`endpoint``$BASE` and `api_key`→bearer into all curl calls. **No `jq` dependency**
the agent parses the JSON itself, portable across Windows/Mac/Linux shells.
## First-run / session-start algorithm (new Step 0)
1. **Check local indicator** (`~/.quicksilver/quicksilver-config.json`).
- **Absent → FRESH INSTALL.** Tell the operator this looks like a first run and
prompt for: (a) endpoint FQDN, (b) API key, (c) name + role. Verify by probing
`GET $BASE/vault/_agent/quicksilver-vault.md` (200/404 = reachable+authorized;
connection error/401 = re-prompt). Write the indicator file (`chmod 600`).
- **Present →** load `endpoint`, `api_key`, `operator`; continue.
2. **Probe vault marker** `_agent/quicksilver-vault.md` with the known creds.
- **404 →** fresh bootstrap (scaffold), seeding `operator-preferences.md`
`## Operator` with the provided name/role, and writing the marker with
`operator:` set (no key).
- **200 →** check `schema_version`, migrate if stale, proceed to normal loading.
## File-by-file changes (genericize + rename in one pass)
- **`.claude-plugin/plugin.json`** — `name`/`description`/`keywords` → quicksilver;
drop "Jason's personal memory vault"; **keep** `author: Jason Stedwell`; bump
`0.5.0``0.6.0`.
- **`README.md`** — title `# quicksilver`; operator-agnostic intro + one line
"Architecture by Jason Stedwell."; rewrite **Configuration** (no hardcoded
server/key; document first-run flow + indicator file); remove "not for
distribution"; ECHO → Quicksilver.
- **`skills/quicksilver/SKILL.md`** — frontmatter `name: quicksilver`, genericize
`description` (strip Jason / Bryan's goldbrain / MPM / wISP; ECHO → Quicksilver);
replace hardcoded `OBSIDIAN_BASE`/`OBSIDIAN_KEY` block with "load from indicator
file"; delete the `echoapi.alwisp.com`-only / retired-`obsidian-memory` paragraph;
rewrite operator-identity paragraph to read identity dynamically; every curl
`Bearer 2412…``$AUTH`, `https://echoapi.alwisp.com``$BASE`; remove goldbrain/Bryan
cross-write rule; "Jason" → "the operator"; add Step 0 to loading; marker path →
`quicksilver-vault.md`.
- **`references/api-reference.md`** — server/key header lines and every curl →
`$BASE`/`$AUTH`; example prose genericized; marker path.
- **`references/bootstrap.md`** — replace hardcoded `AUTH`/`BASE` with load-from-
indicator preamble; add **Step 0: Client configuration (first run)**; seed
`## Operator` from provided name; marker stores operator + schema only; add the
`echo-vault.md``quicksilver-vault.md` rename migration.
- **`references/vault-layout.md`** — genericize operator-preferences + people example
(`<operator-name>.md`); marker path; ECHO → Quicksilver.
- **`references/operating-contract.md`** — confirm operator-agnostic; ECHO →
Quicksilver.
- **`references/session-log-template.md`** — update illustrative key/decision lines;
example slugs `echo-*``quicksilver-*`.
- **`scaffold/quicksilver-vault.md`** (was `echo-vault.md`) — "Quicksilver Vault
Marker"; add `operator:` frontmatter; `managed_by: quicksilver-plugin`; explicit
"no key here".
- **`scaffold/README.vault.md`** — "Quicksilver Memory Vault"; ECHO → Quicksilver.
- **`scaffold/anchors/operator-preferences.seed.md`** — add `{{OPERATOR}}`/`{{ROLE}}`
substitution tokens for `## Operator`.
- **`scaffold/anchors/inbox.seed.md`** — "quicksilver skill".
## Path / file renames (git mv)
- `echo-memory.plugin.src/``quicksilver.plugin.src/`
- `…/skills/echo-memory/``…/skills/quicksilver/`
- `…/scaffold/echo-vault.md``…/scaffold/quicksilver-vault.md`
- `echo-memory.plugin` (packaged artifact) → rebuilt/renamed `quicksilver.plugin`
## Migration impact (Jason's existing vault)
The marker rename means Jason's current vault has the marker at the old path. Fold into
the schema migration: on probe, if `quicksilver-vault.md` is 404 **but**
`echo-vault.md` is 200, treat as a rename migration — PUT the new marker, DELETE the
old, scrub stale `[[echo-vault]]` links. New coworker vaults are fresh and hit the
clean path.
## Security / hygiene
- **Rotate the live key.** `241265fbe…` is committed in plaintext and in git history.
Even after genericizing, history retains it — rotate it on the backend.
- Indicator file holds a secret → write `0600`; it lives in `$HOME`, outside the repo.
## Validation
- **Grep gate:** `grep -ri "echo"` → 0 hits; `grep -ri "jason\|alwisp\|241265\|goldbrain\|bryan"` → only README architect credit + plugin.json author.
- **Fresh install:** no indicator + empty vault → prompts for FQDN/key/name, file
written, vault scaffolded, `## Operator` seeded.
- **Returning user:** indicator + marker present → loads silently, no prompts.
- **Reinstall:** plugin reinstalled, indicator persists in `$HOME` → no re-prompt.
- **Bad endpoint at first run:** unreachable/401 → graceful re-prompt, nothing written.
## Out of scope (v1)
Multiple operators / multiple vaults per machine (single indicator file assumed).