Quirl0.1 RC
ArchitectureDecisions

ADR 0005: Plugin platform state and isolation boundary

Canonical Quirl project documentation synced from docs/decisions/0005-plugin-platform-layer.md.

Context

Phase 3 introduces installed-plugin state, permission grants, supply-chain checksums, and portable isolation contracts. Those responsibilities are not Lua implementation details and do not belong in the semantic catalog or CLI. They need deterministic tests without constructing a VM or touching user files. The design does not yet select a production Wasm engine or WIT toolchain, so importing a large runtime would prematurely freeze an open architectural question.

Decision

Add quirl-plugin as a product layer with one-way dependencies on quirl-core, quirl-catalog, and quirl-contract:

graph BT
    plugin["quirl-plugin"] --> core["quirl-core"]
    plugin --> catalog["quirl-catalog"]
    plugin --> contract["quirl-contract"]
    cli["quirl-cli"] --> plugin
    cli --> lua["quirl-lua"]

quirl-plugin owns versioned deny-unknown plugin and lockfile values, cryptographic source checksums, requested/granted permission diffs, pure copy-on-validate state transitions, doctor reports, and Wasm component/process adapter boundary validation. It does not read or write files, fetch sources, execute adapters, render UI, or construct language runtimes.

The CLI remains the composition root. It resolves explicitly supplied local sources, performs atomic lockfile replacement with a recoverable backup, adapts trusted Lua registrations, and selects text or JSON output. Remote source fetching is deliberately absent from platform v0.1.

quirl-lua remains dependent only on quirl-core among Quirl crates. It accepts explicit string capability grants at construction and exposes Rust-validated, budgeted registration/callback APIs. It does not parse plugin manifests or lockfiles. No native Rust plugin ABI is introduced.

The Wasm boundary uses wasmparser to validate the complete component and its exact WIT host import/guest export, binds the checked-in world hash into lock schema v2, and checks non-zero memory/fuel/deadline budgets without executing code. Wasm components cannot be enabled. The out-of-process boundary validates a relative checksummed executable, protocol version, exact scoped launch grant, message limit, and deadline. ADR 0009 defines its executing v1 handshake, resource enforcement, and crash/cancellation behavior.

Consequences

  • Permission escalation and source tampering are rejected before activation.
  • State transitions can be validated completely before the CLI replaces the current lockfile; failed candidates preserve the last-known-good state.
  • Wasm remains a validated, non-executing boundary; process adapters have a deliberately narrow executing handshake without a stable host callback ABI.
  • SHA-256 is an intentional new dependency for supply-chain integrity; FNV-based schema fingerprints remain identity checks, not authenticity.
  • Panels, live pipelines, reference-shell runners, and platform process behavior remain independently owned contracts. Their subsequent implementation does not add reverse dependencies to this layer.

On this page