Skip to content

feat(personal): install pinned Paseo plugins at sandbox startup - #9

Merged
mogul merged 4 commits into
mainfrom
plugin/quote-notes-auto-install
Nov 7, 2026
Merged

mogul merged 4 commits into
mainfrom
plugin/quote-notes-auto-install

Conversation

@mogul

@mogul mogul commented Nov 7, 2026

Copy link
Copy Markdown
Owner

Context

A new sandbox starts with Paseo's global pluginsEnabled switch unset (treated as off) and no plugins installed, so the author's Paseo plugins had to be installed by hand every time. The personal kit was files-only; a plugin install cannot be a file drop because it needs a running daemon.

What changed

The personal kit gains one background startup command that runs ~/paseo-plugins-install.sh. The script waits for the Paseo daemon from the separate paseo kit, enables plugins, and installs each listed plugin from a pinned source. It always exits 0 and logs to ~/.local/state/paseo/paseo-plugins.log, so it cannot fail a sandbox create. Without the paseo kit it installs nothing.

One commit per plugin:

Commit Plugin Source and pin
1 installer + quote-notes 0.2.2 git:xzthemeofsss/paseo-plugins @ 5ce92527c99a328b28775c7d745f324f2cc84309
2 skills 0.4.0 npm:@gpambrozio/paseo-skills @ 0.4.0
3 mermaid 0.5.0 npm:paseo-plugin-mermaid @ 0.5.0
4 beautiful-chat 0.1.0 git:ABorakati/beautiful-chat @ 42b61d8301b5400a67821bbbfcf99fa8b681dc37

Reviewed and not included: progress (declined), design-canvas (too new, deferred). Not Cafe (its auto-updater would undo the pins).

Reasoning is in personal/docs/decisions/0003-install-paseo-plugins-at-startup.md.

Plan as executed

  • personal/files/home/paseo-plugins-install.sh (new, mode 0755): the installer. install_plugin refuses anything but git:owner/repo with a lowercase 40-hex commit, or npm:package with an exact x.y.z. No registry-id installs.
  • personal/spec.yaml: commands startup entry (background: true), file record, caps.network.allow: [github.com, registry.npmjs.org].
  • personal/scripts/verify section 3d: checks the guard is present, that only install_plugin calls paseo plugin install and keeps --ref "$pin", that every call is pinned, and that an npm plugin implies the npm host.
  • README, TROUBLESHOOTING, AGENTS.md, ADR 0003, ADR 0001 status line, root README row.

Verification

Run on Linux in the dev sandbox:

  • bash personal/scripts/verify: 29 passed, 0 failed (shellcheck included).
  • scripts/validate-kits.py against Patterns pinned at a290d5d8…: all 6 kits valid.
  • pytest scripts/tests: 69 passed. ruff check and ruff format --check: clean. scan_unsafe_shell.py personal: 0 errors, 0 warnings.
  • Live, against a real Paseo 0.12.0 daemon in an isolated PASEO_HOME (real git clones and npm installs): from pluginsEnabled unset, one run enabled plugins and installed all four; paseo plugin ls showed each running at its pin. A second run skipped all four. No daemon: logged and exited 0. Guard refused a branch, a short or uppercase SHA, an npm range or tag, a bare registry id, git: sources with extra segments or @ref, and npm:github: sources before calling paseo. Concurrent run exited at the run lock; TERM left no lock.
  • Verify mutation tests: dropping --ref, an npm tag, an npm github: source, a git @ref, and a trailing comment each fail section 3d.
  • npm tarball sha512s for skills and mermaid were checked against the registry listing and match the lockfiles the daemon wrote.
  • Adversarial review by a sub-agent (two rounds); all findings addressed. No blockers in the final round.

Not verified (be honest about these before merging):

  • A real acq run with the paseo kit on msb or sbx (no acq in the dev sandbox).
  • The paseo kit's newer CLI pins (tested on 0.12.0).
  • A daemon restart landing mid-install; a build outlasting the CLI's own install timeout.
  • git clone behind an HTTPS-inspecting proxy whose CA is not in the system store.
  • How any plugin looks or behaves in a browser, including Beautiful Chat on non-OMP providers.
  • gitleaks (not installed in the dev sandbox; the kit's own credential scan passes).

Rollback

Revert the merge, or drop the commands entry and the paseo-plugins-install.sh record from personal/spec.yaml. Sandboxes already created keep their plugins until recreated (paseo plugin remove <id> removes one).

Security impact

  • Enables Paseo's global plugin switch in every sandbox using this kit. Plugins are trusted, unsandboxed code. The author consented explicitly (2026-11-07).
  • First commands block in this kit, and two new egress hosts (github.com, registry.npmjs.org). caps.network is sandbox-wide, so every agent in the sandbox can reach them.
  • Supply chain: sources are pinned to a commit or exact version and refused otherwise at run time. The sha512 values in the README are for reviewers; nothing checks them at install.
  • beautiful-chat runs npm ci --include=dev at install with the daemon's privileges. At the pinned commit all 361 lockfile entries resolve from registry.npmjs.org with integrity hashes and the only install script is fsevents (macOS only). That is a lockfile-metadata review, not a read of 360 packages. scripts/verify does not inspect a plugin's build list; the README tells whoever bumps a pin to read it.
  • No secrets in the diff.

Known follow-up (once merged)

mermaid and beautiful-chat conflict until Beautiful Chat's Assistant markdown setting is switched off. That setting lives in browser localStorage (per origin), so the kit cannot set it. See the README.


AI assistance: this change was written with OpenCode (claude-sonnet-5.5) and requires human review before merge.

Co-authored-by: OpenCode Agent bmogilefsky@gmail.com

mogul added 4 commits November 7, 2026 08:44
…h quote-notes

Add a background startup command that runs paseo-plugins-install.sh. It waits
for the Paseo daemon from the separate paseo kit, enables the global plugin
switch, and installs each listed plugin from a source pinned to a full commit
(git) or exact version (npm). The first plugin is quote-notes (Codex Style
Annotations 0.2.2) at 5ce92527c99a328b28775c7d745f324f2cc84309.

The kit gains its first commands block and one egress host, github.com. See
personal/docs/decisions/0003. scripts/verify section 3d checks the installer.
…4.0)

Add npm:@gpambrozio/paseo-skills at exact version 0.4.0, the version the Paseo
registry lists. The plugin lists the skills each agent session can use, renders
each SKILL.md and can invoke one. It reads ~/.claude, ~/.codex and ~/.agents/skills,
writes nothing, and has no network or subprocess calls (reviewed at 0.4.0; tarball
sha512 recorded in the README and checked against the registry).

First npm-sourced plugin, so caps.network gains registry.npmjs.org, and
scripts/verify now fails if an npm-sourced plugin is listed without that host.
…0.5.0)

Add npm:paseo-plugin-mermaid at exact version 0.5.0, the version the Paseo
registry lists. The plugin draws mermaid code blocks in chat as diagrams and
opens .mmd files as diagrams. It is client-only: no server code, no network
calls, no subprocess (reviewed at 0.5.0; tarball sha512 recorded in the README
and checked against the registry).
…autiful-chat)

Add git:ABorakati/beautiful-chat at commit 42b61d8301b5400a67821bbbfcf99fa8b681dc37,
the commit the Paseo registry lists. It redraws chat timeline items as typed,
syntax-highlighted cards. Its transformers do not gate on provider, so it applies to
every agent, not only Oh My Pi.

Its manifest runs `npm ci --include=dev` at install, unsandboxed. At the pinned
commit all 361 lockfile entries resolve from registry.npmjs.org with integrity hashes
and the only install script is fsevents (macOS only). Documented in the README and
ADR 0003 as a point-in-time review.

It conflicts with mermaid by default: its "Assistant markdown" setting must be turned
off once per browser origin, which the kit cannot do because the setting lives in
localStorage. Documented in the README.

Hardening from adversarial review of the whole branch:
- install_plugin now also refuses git sources that are not exactly owner/repo and
  npm sources that carry a version, tag or non-registry spec, at run time.
- scripts/verify section 3d requires the git install to keep --ref "$pin" and anchors
  the source shapes.
- The deadline is per plugin, no sleep after the last attempt, and an already
  installed plugin at a different revision is logged, not silently skipped.
- README and ADR corrected: setting name, localStorage origin caveat, what was tested.
@mogul
mogul merged commit 599bf9a into main Nov 7, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant