todo: what has to be true before the plugin ecosystem opens

This commit is contained in:
2026-08-18 02:46:40 +00:00
parent e350c798bb
commit d88bf7b5f5
+29
View File
@@ -298,6 +298,35 @@ pane belonging to the folder you left; and the breadcrumb opted out of that last
restored. Deliberate as written — a dashboard can hold two browsers and one URL cannot serve both —
but worth re-deciding rather than inheriting.
## Plugin ecosystem — before it opens to third parties (2026-08-18)
Not now. Months away. Recorded so it is not re-derived.
- [ ] **A plugin install is not pinned, so a review would bind a repository rather than code.**
`fetch.ts:70` is `git clone --depth 1 <source>` — no ref — so it takes whatever the default branch
points at when the install runs. A plugin reviewed at commit X installs at whatever was pushed
since, and `--depth 1` leaves no history to compare against.
This is the shape of the npm attack already documented in `CLAUDE.md` (2026-08-04), and the same
shape as the Chrome Web Store's real failures — not bad extensions passing review, but good ones
sold or compromised and then pushing an update to users who had already accepted them.
Fix: a `reviewedCommit` on the catalogue entry, checkout detached at that SHA, and **verify
`rev-parse HEAD` matches or refuse**. The verification is the part that matters. An update then
becomes "a new reviewed SHA exists" — a catalogue change rather than something the author triggers.
- [ ] **Third-party plugin sidecars are unconfined.** A plugin sidecar runs `bun run <script>` with
`cwd: PLATFORM_DIR`, so Bun auto-loads `.env` and it gets `POSTGRES_URL`; it runs as the service
user, which owns `secrets/officer-keys.db` and can therefore mint an owner JWT. Fine for
first-party plugins, total compromise for anyone else's.
The mechanism to fix it already exists and is pointed elsewhere: `spawn-as-member.ts` drops
privileges with `setpriv --reset-env` and a six-name allowlist for exactly this reason.
- [ ] **No install-from-git-URL.** The catalogue is the only route for a remote plugin, so the
"build your own, give it to a friend" path has no affordance. Small, and needed before the
unofficial channel is real.
## Plugin system — gaps the email extraction found (2026-08-18)
- [ ] **A plugin cannot declare its own npm dependencies, so the PLATFORM is carrying them.** `imapflow`,