Files
clide/decisions/extensions.md
T
jpmschweitzerandClaude 4d515ce51e scaffold decisions/ with backlog from planning sessions
Adopt settled-reach's Q&D record convention. Confirmed decisions
live under decisions/<domain>.md as D-NNN; open questions under
questions-<domain>.md as Q-NNN; rejected alternatives in rejected.md
as R-NNN. Markdown is source of truth; .pql/pql.db (added later) is a
query index.

Backlog captured from the Tier-0 Flutter planning sessions: bare
WidgetsApp, theme pipeline, kernel admission rule, feature-first
layout, a11y + i18n as Tier-0 contracts, test pyramid, kanban over
Scrum, pql-owns-planning, Python stopgap sunset clause.

ADR migration (D-001, D-003-D-006 confirmed, R-002 rejected) is
staged for the next commit so the diff stays readable.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 17:10:42 +02:00

47 lines
4.2 KiB
Markdown

# Extension Decisions
Extension contract, Lua runtime, grain, contribution points.
---
### D-015: Extension grain — container-level, multi-contribution
- **Date:** 2026-04-21
- **Decision:** An extension is a shipping unit that contributes one or more named contributions (panel, command, theme, keybinding, language, layout, provider, view). Grain is container-sized — a single `builtin.git` extension contributes panel + commands + keybindings + status-bar items; we do not ship one extension per contribution.
- **Rationale:** Finer grain (one extension per contribution) multiplies manifest files with no win and fragments ownership. Coarser grain (one mega-extension per domain) hides which parts a user might reasonably disable.
- **Cost:** Extension authors make a taste call about grouping; disagreements go to review.
- **Raised by:** 2026-04-21 planning.
### D-016: Built-ins in Dart, third-party in sandboxed Lua
- **Date:** 2026-04-21
- **Decision:** Bundled extensions (every `app/lib/builtin/<name>`) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via the `ptyc`-peer Lua runtime (see [D-019](#d-019-lua-runtime-as-ptyc-peer-supporter-tool)). The contribution contract is language-agnostic — same contribution shapes, same manifest schema.
- **Rationale:** Dart built-ins get full SDK power (custom painters, isolates, FFI); third-party Lua gets a narrow capability API, no arbitrary syscalls, no deps on pub.dev. VS Code's Node-runs-with-full-power model is a supply-chain nightmare we're explicitly rejecting.
- **Cost:** Two implementation paths for the same contract; we pay in API design to keep them equivalent at the seams.
- **Raised by:** 2026-04-21 planning.
### D-017: Panels are extension-shaped from day one
- **Date:** 2026-04-21
- **Decision:** Every bundled panel (file tree, git, problems, pql query, terminal, etc.) is a contribution on the extension contract, not a hardcoded widget tree in the panel manager. First party contributes via Dart; third party contributes via Lua; same contract.
- **Rationale:** Forces the contract to be real on day one. The alternative ("extensions can contribute panels *later*") always becomes "the contract doesn't quite fit our bundled panels, so built-ins get a shortcut" — and the shortcut becomes permanent.
- **Cost:** Every panel goes through the manifest/registration path even when it's trivial. Price paid once.
- **Raised by:** 2026-04-21 planning.
### D-018: YAML for themes + manifests; JSON for i18n catalogs
- **Date:** 2026-04-21
- **Decision:** Themes and extension manifests are YAML; i18n catalogues are JSON (fframe parity — see [D-021](accessibility.md#d-021-i18n-is-a-tier-0-contract)).
- **Rationale:** YAML for human-edited config files (themes, manifests) — comments, multi-line strings, less noise. JSON for machine-written / machine-read files (i18n catalogs get generated by translation tooling eventually). Mixing is fine; each format is where it's best.
- **Cost:** Two parsers in the tree. `yaml: 3.1.3` is exact-pinned.
- **Raised by:** 2026-04-21 planning.
### D-019: Lua runtime as `ptyc`-peer supporter tool
- **Date:** 2026-04-21
- **Decision:** Third-party extensions run Lua inside a sandboxed runtime (working name TBD; same peer-status as `ptyc` and `pql`). The runtime vendors liblua, links from Dart via `dart:ffi`, exposes a narrow capability API, and takes contributions as a declarative render-intent DSL (widget shapes, not arbitrary widget code).
- **Rationale:** Lua is small, embeddable, battle-tested (Neovim, World of Warcraft, Redis). Native sandboxing at the VM level is cheap. A declarative render-intent DSL keeps "run arbitrary Flutter widgets from Lua" off the table — the runtime interprets the DSL into Dart widgets, which keeps Tier 6 supply-chain risk bounded.
- **Cost:** Runtime is a separate supporter tool to build; ffi is tricky. Deferred to Tier 6; only the slot is reserved now.
- **Raised by:** 2026-04-21 planning.
---
*See also the existing `builtin.grammars_core` stub for tree-sitter
questions ([Q-015](questions-process.md#q-015-editor-tab-full-lsp-vs-tree-sitter-only),
[Q-016](questions-process.md#q-016-tree-sitter-dart-grammar-maintenance)).*