M5 implementation plan — agent and UI disclosure
Task breakdown for milestone M5 of sandbox-package-design.md. The one-line prompt tier and the CodeAct session allowlist shipped with M1; M5 is the documentation layer on top: full SKILL.md retrieval under the trust rules, package-picker rendering, and Package Manager consent language. It lands only after the untrusted-content policy below is wired exactly as designed — quoting is risk reduction, not isolation, so the policy is about when the agent sees pack docs, not how they are delimited.
Landed. All five tasks shipped together; see the M5 checkpoint in sandbox-package-design.md for what is where.
Task 1 — Full SKILL.md parsing at discovery
M0 validates only size and minimal frontmatter shape. Hoist the
existing AgentSkill parser (packages/agents/src/agent.ts) so
node-sdk can call it — per the design, format and parser are the
existing skill machinery, moved to where discovery lives (the
agents package depends on node-sdk, so the shared parser moves down
the dependency order, likely into node-sdk itself or protocol,
mirroring how code-analysis.ts serves both). Discovery output
gains the parsed skill (title, description, body) per pack; parse
failures stay warning-grade — a frontmatter typo must never disable
working modules. A pack exposing several specifiers carries one
skill with a section per module.
Task 2 — Trust-scoped disclosure paths
- Trusted pack (on the pack-loader allowlist): its skill registers through the normal skill system and can be injected like any other skill.
- Untrusted pack: the body is never injected. The agent sees it
only as untrusted tool output, and only after the package has
been chosen for the session (on the CodeAct session allowlist from
M1). A new tool —
get_sandbox_package_docs(specifier)— serves the body wrapped as untrusted content, refusing specifiers not on the session allowlist. - The ambient one-line tier stays exactly what M1 shipped: manifest-derived, strict length and character limits, never arbitrary pack text. M5 adds no third tier.
Task 3 — Code node package picker
The Code node property panel gets the package picker: session-installed
sandbox packs with their one-liners, and the rendered SKILL.md on
selection (same file the agent retrieves; rendering is for the human).
The picker writes SandboxModuleDeclarations onto the node’s
packages property (M1’s shape), stamping resolvedPackVersion and
contentDigest from the catalog summary. The consent wording is the
design’s: “runs inside your workflows with the node’s capabilities” —
never “no trust needed”. UI per repo rules: ui_primitives only, design
tokens, catalog data over the existing packs.sandboxModules tRPC
surface (extended with the rendered skill body by opaque request, not
ambient in the summaries).
Task 4 — Package Manager consent language
Settings → Packages already shows mode chips and the trust-and-rebuild action (M0). M5 adds the sandbox-consent sentence to sandbox-only and hybrid packs, the per-module one-liners, and the SKILL.md view. Install flow wording states what importing means at the moment of install, per the trust model.
Task 5 — Drift tests and prompt-budget guard
The M1 drift tests pin the one-line tier. M5 adds: the disclosure
tool’s output is wrapped as untrusted content (string-pinned, like the
existing prompt drift tests); the one-liner derivation enforces its
length/charset limits against adversarial manifest fixtures (control
characters, prompt-injection phrases in description — the limits are
the defense, the test proves them); and skill registration for a
trusted pack does not leak into a session where the pack is not
allowlisted.
Sequencing
Task 1 → 2 (parser before disclosure), then 3 and 4 in parallel (both consume Task 2’s surfaces), Task 5 throughout. Depends on M1 (session allowlist, declarations); benefits from M2 (a picker-declared pack should run in the browser) but does not require it.
Exit criteria
- A trusted fixture pack’s skill registers; the same pack untrusted yields docs only via the tool, only when session-allowed, wrapped as untrusted output.
- The picker produces valid stamped declarations and shows the consent wording.
- Adversarial manifest fixtures cannot place uncapped or unfiltered text into any always-on prompt tier.
npm run checkgreen.